summaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Python
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tools/python3/src/Python')
-rw-r--r--contrib/tools/python3/src/Python/Python-ast.c10854
-rw-r--r--contrib/tools/python3/src/Python/_warnings.c1430
-rw-r--r--contrib/tools/python3/src/Python/asdl.c64
-rw-r--r--contrib/tools/python3/src/Python/ast.c5858
-rw-r--r--contrib/tools/python3/src/Python/ast_opt.c752
-rw-r--r--contrib/tools/python3/src/Python/ast_unparse.c972
-rw-r--r--contrib/tools/python3/src/Python/bltinmodule.c2843
-rw-r--r--contrib/tools/python3/src/Python/bootstrap_hash.c623
-rw-r--r--contrib/tools/python3/src/Python/ceval.c5699
-rw-r--r--contrib/tools/python3/src/Python/ceval_gil.h331
-rw-r--r--contrib/tools/python3/src/Python/clinic/_warnings.c.h74
-rw-r--r--contrib/tools/python3/src/Python/clinic/bltinmodule.c.h858
-rw-r--r--contrib/tools/python3/src/Python/clinic/context.c.h180
-rw-r--r--contrib/tools/python3/src/Python/clinic/import.c.h457
-rw-r--r--contrib/tools/python3/src/Python/clinic/marshal.c.h168
-rw-r--r--contrib/tools/python3/src/Python/clinic/sysmodule.c.h973
-rw-r--r--contrib/tools/python3/src/Python/clinic/traceback.c.h62
-rw-r--r--contrib/tools/python3/src/Python/codecs.c1535
-rw-r--r--contrib/tools/python3/src/Python/compile.c6083
-rw-r--r--contrib/tools/python3/src/Python/condvar.h309
-rw-r--r--contrib/tools/python3/src/Python/context.c1319
-rw-r--r--contrib/tools/python3/src/Python/dtoa.c2859
-rw-r--r--contrib/tools/python3/src/Python/dynamic_annotations.c154
-rw-r--r--contrib/tools/python3/src/Python/dynload_shlib.c133
-rw-r--r--contrib/tools/python3/src/Python/dynload_win.c285
-rw-r--r--contrib/tools/python3/src/Python/errors.c1742
-rw-r--r--contrib/tools/python3/src/Python/fileutils.c2276
-rw-r--r--contrib/tools/python3/src/Python/formatter_unicode.c1600
-rw-r--r--contrib/tools/python3/src/Python/frozen.c50
-rw-r--r--contrib/tools/python3/src/Python/frozenmain.c129
-rw-r--r--contrib/tools/python3/src/Python/future.c158
-rw-r--r--contrib/tools/python3/src/Python/getargs.c2870
-rw-r--r--contrib/tools/python3/src/Python/getcompiler.c27
-rw-r--r--contrib/tools/python3/src/Python/getcopyright.c23
-rw-r--r--contrib/tools/python3/src/Python/getopt.c175
-rw-r--r--contrib/tools/python3/src/Python/getplatform.c12
-rw-r--r--contrib/tools/python3/src/Python/getversion.c15
-rw-r--r--contrib/tools/python3/src/Python/graminit.c2688
-rw-r--r--contrib/tools/python3/src/Python/hamt.c2996
-rw-r--r--contrib/tools/python3/src/Python/hashtable.c417
-rw-r--r--contrib/tools/python3/src/Python/import.c2512
-rw-r--r--contrib/tools/python3/src/Python/importdl.c249
-rw-r--r--contrib/tools/python3/src/Python/importdl.h27
-rw-r--r--contrib/tools/python3/src/Python/importlib.h1812
-rw-r--r--contrib/tools/python3/src/Python/importlib_external.h2825
-rw-r--r--contrib/tools/python3/src/Python/importlib_zipimport.h1079
-rw-r--r--contrib/tools/python3/src/Python/initconfig.c2765
-rw-r--r--contrib/tools/python3/src/Python/marshal.c1822
-rw-r--r--contrib/tools/python3/src/Python/modsupport.c703
-rw-r--r--contrib/tools/python3/src/Python/mysnprintf.c111
-rw-r--r--contrib/tools/python3/src/Python/mystrtoul.c291
-rw-r--r--contrib/tools/python3/src/Python/opcode_targets.h258
-rw-r--r--contrib/tools/python3/src/Python/pathconfig.c803
-rw-r--r--contrib/tools/python3/src/Python/peephole.c538
-rw-r--r--contrib/tools/python3/src/Python/preconfig.c968
-rw-r--r--contrib/tools/python3/src/Python/pyarena.c210
-rw-r--r--contrib/tools/python3/src/Python/pyctype.c214
-rw-r--r--contrib/tools/python3/src/Python/pyfpe.c15
-rw-r--r--contrib/tools/python3/src/Python/pyhash.c441
-rw-r--r--contrib/tools/python3/src/Python/pylifecycle.c2559
-rw-r--r--contrib/tools/python3/src/Python/pymath.c96
-rw-r--r--contrib/tools/python3/src/Python/pystate.c1833
-rw-r--r--contrib/tools/python3/src/Python/pystrcmp.c30
-rw-r--r--contrib/tools/python3/src/Python/pystrhex.c172
-rw-r--r--contrib/tools/python3/src/Python/pystrtod.c1307
-rw-r--r--contrib/tools/python3/src/Python/pythonrun.c1880
-rw-r--r--contrib/tools/python3/src/Python/pytime.c1135
-rw-r--r--contrib/tools/python3/src/Python/structmember.c291
-rw-r--r--contrib/tools/python3/src/Python/symtable.c1936
-rw-r--r--contrib/tools/python3/src/Python/sysmodule.c3327
-rw-r--r--contrib/tools/python3/src/Python/thread.c226
-rw-r--r--contrib/tools/python3/src/Python/thread_nt.h505
-rw-r--r--contrib/tools/python3/src/Python/thread_pthread.h926
-rw-r--r--contrib/tools/python3/src/Python/traceback.c951
-rw-r--r--contrib/tools/python3/src/Python/wordcode_helpers.h44
75 files changed, 94914 insertions, 0 deletions
diff --git a/contrib/tools/python3/src/Python/Python-ast.c b/contrib/tools/python3/src/Python/Python-ast.c
new file mode 100644
index 00000000000..8b1c594a878
--- /dev/null
+++ b/contrib/tools/python3/src/Python/Python-ast.c
@@ -0,0 +1,10854 @@
+/* File automatically generated by Parser/asdl_c.py. */
+
+#include <stddef.h>
+
+#include "Python.h"
+#include "Python-ast.h"
+#include "structmember.h" // PyMemberDef
+
+typedef struct {
+ int initialized;
+ PyObject *AST_type;
+ PyObject *Add_singleton;
+ PyObject *Add_type;
+ PyObject *And_singleton;
+ PyObject *And_type;
+ PyObject *AnnAssign_type;
+ PyObject *Assert_type;
+ PyObject *Assign_type;
+ PyObject *AsyncFor_type;
+ PyObject *AsyncFunctionDef_type;
+ PyObject *AsyncWith_type;
+ PyObject *Attribute_type;
+ PyObject *AugAssign_type;
+ PyObject *Await_type;
+ PyObject *BinOp_type;
+ PyObject *BitAnd_singleton;
+ PyObject *BitAnd_type;
+ PyObject *BitOr_singleton;
+ PyObject *BitOr_type;
+ PyObject *BitXor_singleton;
+ PyObject *BitXor_type;
+ PyObject *BoolOp_type;
+ PyObject *Break_type;
+ PyObject *Call_type;
+ PyObject *ClassDef_type;
+ PyObject *Compare_type;
+ PyObject *Constant_type;
+ PyObject *Continue_type;
+ PyObject *Del_singleton;
+ PyObject *Del_type;
+ PyObject *Delete_type;
+ PyObject *DictComp_type;
+ PyObject *Dict_type;
+ PyObject *Div_singleton;
+ PyObject *Div_type;
+ PyObject *Eq_singleton;
+ PyObject *Eq_type;
+ PyObject *ExceptHandler_type;
+ PyObject *Expr_type;
+ PyObject *Expression_type;
+ PyObject *FloorDiv_singleton;
+ PyObject *FloorDiv_type;
+ PyObject *For_type;
+ PyObject *FormattedValue_type;
+ PyObject *FunctionDef_type;
+ PyObject *FunctionType_type;
+ PyObject *GeneratorExp_type;
+ PyObject *Global_type;
+ PyObject *GtE_singleton;
+ PyObject *GtE_type;
+ PyObject *Gt_singleton;
+ PyObject *Gt_type;
+ PyObject *IfExp_type;
+ PyObject *If_type;
+ PyObject *ImportFrom_type;
+ PyObject *Import_type;
+ PyObject *In_singleton;
+ PyObject *In_type;
+ PyObject *Interactive_type;
+ PyObject *Invert_singleton;
+ PyObject *Invert_type;
+ PyObject *IsNot_singleton;
+ PyObject *IsNot_type;
+ PyObject *Is_singleton;
+ PyObject *Is_type;
+ PyObject *JoinedStr_type;
+ PyObject *LShift_singleton;
+ PyObject *LShift_type;
+ PyObject *Lambda_type;
+ PyObject *ListComp_type;
+ PyObject *List_type;
+ PyObject *Load_singleton;
+ PyObject *Load_type;
+ PyObject *LtE_singleton;
+ PyObject *LtE_type;
+ PyObject *Lt_singleton;
+ PyObject *Lt_type;
+ PyObject *MatMult_singleton;
+ PyObject *MatMult_type;
+ PyObject *Mod_singleton;
+ PyObject *Mod_type;
+ PyObject *Module_type;
+ PyObject *Mult_singleton;
+ PyObject *Mult_type;
+ PyObject *Name_type;
+ PyObject *NamedExpr_type;
+ PyObject *Nonlocal_type;
+ PyObject *NotEq_singleton;
+ PyObject *NotEq_type;
+ PyObject *NotIn_singleton;
+ PyObject *NotIn_type;
+ PyObject *Not_singleton;
+ PyObject *Not_type;
+ PyObject *Or_singleton;
+ PyObject *Or_type;
+ PyObject *Pass_type;
+ PyObject *Pow_singleton;
+ PyObject *Pow_type;
+ PyObject *RShift_singleton;
+ PyObject *RShift_type;
+ PyObject *Raise_type;
+ PyObject *Return_type;
+ PyObject *SetComp_type;
+ PyObject *Set_type;
+ PyObject *Slice_type;
+ PyObject *Starred_type;
+ PyObject *Store_singleton;
+ PyObject *Store_type;
+ PyObject *Sub_singleton;
+ PyObject *Sub_type;
+ PyObject *Subscript_type;
+ PyObject *Try_type;
+ PyObject *Tuple_type;
+ PyObject *TypeIgnore_type;
+ PyObject *UAdd_singleton;
+ PyObject *UAdd_type;
+ PyObject *USub_singleton;
+ PyObject *USub_type;
+ PyObject *UnaryOp_type;
+ PyObject *While_type;
+ PyObject *With_type;
+ PyObject *YieldFrom_type;
+ PyObject *Yield_type;
+ PyObject *__dict__;
+ PyObject *__doc__;
+ PyObject *__module__;
+ PyObject *_attributes;
+ PyObject *_fields;
+ PyObject *alias_type;
+ PyObject *annotation;
+ PyObject *arg;
+ PyObject *arg_type;
+ PyObject *args;
+ PyObject *argtypes;
+ PyObject *arguments_type;
+ PyObject *asname;
+ PyObject *ast;
+ PyObject *attr;
+ PyObject *bases;
+ PyObject *body;
+ PyObject *boolop_type;
+ PyObject *cause;
+ PyObject *cmpop_type;
+ PyObject *col_offset;
+ PyObject *comparators;
+ PyObject *comprehension_type;
+ PyObject *context_expr;
+ PyObject *conversion;
+ PyObject *ctx;
+ PyObject *decorator_list;
+ PyObject *defaults;
+ PyObject *elt;
+ PyObject *elts;
+ PyObject *end_col_offset;
+ PyObject *end_lineno;
+ PyObject *exc;
+ PyObject *excepthandler_type;
+ PyObject *expr_context_type;
+ PyObject *expr_type;
+ PyObject *finalbody;
+ PyObject *format_spec;
+ PyObject *func;
+ PyObject *generators;
+ PyObject *handlers;
+ PyObject *id;
+ PyObject *ifs;
+ PyObject *is_async;
+ PyObject *items;
+ PyObject *iter;
+ PyObject *key;
+ PyObject *keys;
+ PyObject *keyword_type;
+ PyObject *keywords;
+ PyObject *kind;
+ PyObject *kw_defaults;
+ PyObject *kwarg;
+ PyObject *kwonlyargs;
+ PyObject *left;
+ PyObject *level;
+ PyObject *lineno;
+ PyObject *lower;
+ PyObject *mod_type;
+ PyObject *module;
+ PyObject *msg;
+ PyObject *name;
+ PyObject *names;
+ PyObject *op;
+ PyObject *operand;
+ PyObject *operator_type;
+ PyObject *ops;
+ PyObject *optional_vars;
+ PyObject *orelse;
+ PyObject *posonlyargs;
+ PyObject *returns;
+ PyObject *right;
+ PyObject *simple;
+ PyObject *slice;
+ PyObject *step;
+ PyObject *stmt_type;
+ PyObject *tag;
+ PyObject *target;
+ PyObject *targets;
+ PyObject *test;
+ PyObject *type;
+ PyObject *type_comment;
+ PyObject *type_ignore_type;
+ PyObject *type_ignores;
+ PyObject *unaryop_type;
+ PyObject *upper;
+ PyObject *value;
+ PyObject *values;
+ PyObject *vararg;
+ PyObject *withitem_type;
+} astmodulestate;
+
+
+// Forward declaration
+static int init_types(astmodulestate *state);
+
+// bpo-41194, bpo-41261, bpo-41631: The _ast module uses a global state.
+static astmodulestate global_ast_state = {0};
+
+static astmodulestate*
+get_global_ast_state(void)
+{
+ astmodulestate* state = &global_ast_state;
+ if (!init_types(state)) {
+ return NULL;
+ }
+ return state;
+}
+
+static astmodulestate*
+get_ast_state(PyObject* Py_UNUSED(module))
+{
+ astmodulestate* state = get_global_ast_state();
+ // get_ast_state() must only be called after _ast module is imported,
+ // and astmodule_exec() calls init_types()
+ assert(state != NULL);
+ return state;
+}
+
+void _PyAST_Fini()
+{
+ astmodulestate* state = &global_ast_state;
+ Py_CLEAR(state->AST_type);
+ Py_CLEAR(state->Add_singleton);
+ Py_CLEAR(state->Add_type);
+ Py_CLEAR(state->And_singleton);
+ Py_CLEAR(state->And_type);
+ Py_CLEAR(state->AnnAssign_type);
+ Py_CLEAR(state->Assert_type);
+ Py_CLEAR(state->Assign_type);
+ Py_CLEAR(state->AsyncFor_type);
+ Py_CLEAR(state->AsyncFunctionDef_type);
+ Py_CLEAR(state->AsyncWith_type);
+ Py_CLEAR(state->Attribute_type);
+ Py_CLEAR(state->AugAssign_type);
+ Py_CLEAR(state->Await_type);
+ Py_CLEAR(state->BinOp_type);
+ Py_CLEAR(state->BitAnd_singleton);
+ Py_CLEAR(state->BitAnd_type);
+ Py_CLEAR(state->BitOr_singleton);
+ Py_CLEAR(state->BitOr_type);
+ Py_CLEAR(state->BitXor_singleton);
+ Py_CLEAR(state->BitXor_type);
+ Py_CLEAR(state->BoolOp_type);
+ Py_CLEAR(state->Break_type);
+ Py_CLEAR(state->Call_type);
+ Py_CLEAR(state->ClassDef_type);
+ Py_CLEAR(state->Compare_type);
+ Py_CLEAR(state->Constant_type);
+ Py_CLEAR(state->Continue_type);
+ Py_CLEAR(state->Del_singleton);
+ Py_CLEAR(state->Del_type);
+ Py_CLEAR(state->Delete_type);
+ Py_CLEAR(state->DictComp_type);
+ Py_CLEAR(state->Dict_type);
+ Py_CLEAR(state->Div_singleton);
+ Py_CLEAR(state->Div_type);
+ Py_CLEAR(state->Eq_singleton);
+ Py_CLEAR(state->Eq_type);
+ Py_CLEAR(state->ExceptHandler_type);
+ Py_CLEAR(state->Expr_type);
+ Py_CLEAR(state->Expression_type);
+ Py_CLEAR(state->FloorDiv_singleton);
+ Py_CLEAR(state->FloorDiv_type);
+ Py_CLEAR(state->For_type);
+ Py_CLEAR(state->FormattedValue_type);
+ Py_CLEAR(state->FunctionDef_type);
+ Py_CLEAR(state->FunctionType_type);
+ Py_CLEAR(state->GeneratorExp_type);
+ Py_CLEAR(state->Global_type);
+ Py_CLEAR(state->GtE_singleton);
+ Py_CLEAR(state->GtE_type);
+ Py_CLEAR(state->Gt_singleton);
+ Py_CLEAR(state->Gt_type);
+ Py_CLEAR(state->IfExp_type);
+ Py_CLEAR(state->If_type);
+ Py_CLEAR(state->ImportFrom_type);
+ Py_CLEAR(state->Import_type);
+ Py_CLEAR(state->In_singleton);
+ Py_CLEAR(state->In_type);
+ Py_CLEAR(state->Interactive_type);
+ Py_CLEAR(state->Invert_singleton);
+ Py_CLEAR(state->Invert_type);
+ Py_CLEAR(state->IsNot_singleton);
+ Py_CLEAR(state->IsNot_type);
+ Py_CLEAR(state->Is_singleton);
+ Py_CLEAR(state->Is_type);
+ Py_CLEAR(state->JoinedStr_type);
+ Py_CLEAR(state->LShift_singleton);
+ Py_CLEAR(state->LShift_type);
+ Py_CLEAR(state->Lambda_type);
+ Py_CLEAR(state->ListComp_type);
+ Py_CLEAR(state->List_type);
+ Py_CLEAR(state->Load_singleton);
+ Py_CLEAR(state->Load_type);
+ Py_CLEAR(state->LtE_singleton);
+ Py_CLEAR(state->LtE_type);
+ Py_CLEAR(state->Lt_singleton);
+ Py_CLEAR(state->Lt_type);
+ Py_CLEAR(state->MatMult_singleton);
+ Py_CLEAR(state->MatMult_type);
+ Py_CLEAR(state->Mod_singleton);
+ Py_CLEAR(state->Mod_type);
+ Py_CLEAR(state->Module_type);
+ Py_CLEAR(state->Mult_singleton);
+ Py_CLEAR(state->Mult_type);
+ Py_CLEAR(state->Name_type);
+ Py_CLEAR(state->NamedExpr_type);
+ Py_CLEAR(state->Nonlocal_type);
+ Py_CLEAR(state->NotEq_singleton);
+ Py_CLEAR(state->NotEq_type);
+ Py_CLEAR(state->NotIn_singleton);
+ Py_CLEAR(state->NotIn_type);
+ Py_CLEAR(state->Not_singleton);
+ Py_CLEAR(state->Not_type);
+ Py_CLEAR(state->Or_singleton);
+ Py_CLEAR(state->Or_type);
+ Py_CLEAR(state->Pass_type);
+ Py_CLEAR(state->Pow_singleton);
+ Py_CLEAR(state->Pow_type);
+ Py_CLEAR(state->RShift_singleton);
+ Py_CLEAR(state->RShift_type);
+ Py_CLEAR(state->Raise_type);
+ Py_CLEAR(state->Return_type);
+ Py_CLEAR(state->SetComp_type);
+ Py_CLEAR(state->Set_type);
+ Py_CLEAR(state->Slice_type);
+ Py_CLEAR(state->Starred_type);
+ Py_CLEAR(state->Store_singleton);
+ Py_CLEAR(state->Store_type);
+ Py_CLEAR(state->Sub_singleton);
+ Py_CLEAR(state->Sub_type);
+ Py_CLEAR(state->Subscript_type);
+ Py_CLEAR(state->Try_type);
+ Py_CLEAR(state->Tuple_type);
+ Py_CLEAR(state->TypeIgnore_type);
+ Py_CLEAR(state->UAdd_singleton);
+ Py_CLEAR(state->UAdd_type);
+ Py_CLEAR(state->USub_singleton);
+ Py_CLEAR(state->USub_type);
+ Py_CLEAR(state->UnaryOp_type);
+ Py_CLEAR(state->While_type);
+ Py_CLEAR(state->With_type);
+ Py_CLEAR(state->YieldFrom_type);
+ Py_CLEAR(state->Yield_type);
+ Py_CLEAR(state->__dict__);
+ Py_CLEAR(state->__doc__);
+ Py_CLEAR(state->__module__);
+ Py_CLEAR(state->_attributes);
+ Py_CLEAR(state->_fields);
+ Py_CLEAR(state->alias_type);
+ Py_CLEAR(state->annotation);
+ Py_CLEAR(state->arg);
+ Py_CLEAR(state->arg_type);
+ Py_CLEAR(state->args);
+ Py_CLEAR(state->argtypes);
+ Py_CLEAR(state->arguments_type);
+ Py_CLEAR(state->asname);
+ Py_CLEAR(state->ast);
+ Py_CLEAR(state->attr);
+ Py_CLEAR(state->bases);
+ Py_CLEAR(state->body);
+ Py_CLEAR(state->boolop_type);
+ Py_CLEAR(state->cause);
+ Py_CLEAR(state->cmpop_type);
+ Py_CLEAR(state->col_offset);
+ Py_CLEAR(state->comparators);
+ Py_CLEAR(state->comprehension_type);
+ Py_CLEAR(state->context_expr);
+ Py_CLEAR(state->conversion);
+ Py_CLEAR(state->ctx);
+ Py_CLEAR(state->decorator_list);
+ Py_CLEAR(state->defaults);
+ Py_CLEAR(state->elt);
+ Py_CLEAR(state->elts);
+ Py_CLEAR(state->end_col_offset);
+ Py_CLEAR(state->end_lineno);
+ Py_CLEAR(state->exc);
+ Py_CLEAR(state->excepthandler_type);
+ Py_CLEAR(state->expr_context_type);
+ Py_CLEAR(state->expr_type);
+ Py_CLEAR(state->finalbody);
+ Py_CLEAR(state->format_spec);
+ Py_CLEAR(state->func);
+ Py_CLEAR(state->generators);
+ Py_CLEAR(state->handlers);
+ Py_CLEAR(state->id);
+ Py_CLEAR(state->ifs);
+ Py_CLEAR(state->is_async);
+ Py_CLEAR(state->items);
+ Py_CLEAR(state->iter);
+ Py_CLEAR(state->key);
+ Py_CLEAR(state->keys);
+ Py_CLEAR(state->keyword_type);
+ Py_CLEAR(state->keywords);
+ Py_CLEAR(state->kind);
+ Py_CLEAR(state->kw_defaults);
+ Py_CLEAR(state->kwarg);
+ Py_CLEAR(state->kwonlyargs);
+ Py_CLEAR(state->left);
+ Py_CLEAR(state->level);
+ Py_CLEAR(state->lineno);
+ Py_CLEAR(state->lower);
+ Py_CLEAR(state->mod_type);
+ Py_CLEAR(state->module);
+ Py_CLEAR(state->msg);
+ Py_CLEAR(state->name);
+ Py_CLEAR(state->names);
+ Py_CLEAR(state->op);
+ Py_CLEAR(state->operand);
+ Py_CLEAR(state->operator_type);
+ Py_CLEAR(state->ops);
+ Py_CLEAR(state->optional_vars);
+ Py_CLEAR(state->orelse);
+ Py_CLEAR(state->posonlyargs);
+ Py_CLEAR(state->returns);
+ Py_CLEAR(state->right);
+ Py_CLEAR(state->simple);
+ Py_CLEAR(state->slice);
+ Py_CLEAR(state->step);
+ Py_CLEAR(state->stmt_type);
+ Py_CLEAR(state->tag);
+ Py_CLEAR(state->target);
+ Py_CLEAR(state->targets);
+ Py_CLEAR(state->test);
+ Py_CLEAR(state->type);
+ Py_CLEAR(state->type_comment);
+ Py_CLEAR(state->type_ignore_type);
+ Py_CLEAR(state->type_ignores);
+ Py_CLEAR(state->unaryop_type);
+ Py_CLEAR(state->upper);
+ Py_CLEAR(state->value);
+ Py_CLEAR(state->values);
+ Py_CLEAR(state->vararg);
+ Py_CLEAR(state->withitem_type);
+
+ state->initialized = 0;
+}
+
+static int init_identifiers(astmodulestate *state)
+{
+ if ((state->__dict__ = PyUnicode_InternFromString("__dict__")) == NULL) return 0;
+ if ((state->__doc__ = PyUnicode_InternFromString("__doc__")) == NULL) return 0;
+ if ((state->__module__ = PyUnicode_InternFromString("__module__")) == NULL) return 0;
+ if ((state->_attributes = PyUnicode_InternFromString("_attributes")) == NULL) return 0;
+ if ((state->_fields = PyUnicode_InternFromString("_fields")) == NULL) return 0;
+ if ((state->annotation = PyUnicode_InternFromString("annotation")) == NULL) return 0;
+ if ((state->arg = PyUnicode_InternFromString("arg")) == NULL) return 0;
+ if ((state->args = PyUnicode_InternFromString("args")) == NULL) return 0;
+ if ((state->argtypes = PyUnicode_InternFromString("argtypes")) == NULL) return 0;
+ if ((state->asname = PyUnicode_InternFromString("asname")) == NULL) return 0;
+ if ((state->ast = PyUnicode_InternFromString("ast")) == NULL) return 0;
+ if ((state->attr = PyUnicode_InternFromString("attr")) == NULL) return 0;
+ if ((state->bases = PyUnicode_InternFromString("bases")) == NULL) return 0;
+ if ((state->body = PyUnicode_InternFromString("body")) == NULL) return 0;
+ if ((state->cause = PyUnicode_InternFromString("cause")) == NULL) return 0;
+ if ((state->col_offset = PyUnicode_InternFromString("col_offset")) == NULL) return 0;
+ if ((state->comparators = PyUnicode_InternFromString("comparators")) == NULL) return 0;
+ if ((state->context_expr = PyUnicode_InternFromString("context_expr")) == NULL) return 0;
+ if ((state->conversion = PyUnicode_InternFromString("conversion")) == NULL) return 0;
+ if ((state->ctx = PyUnicode_InternFromString("ctx")) == NULL) return 0;
+ if ((state->decorator_list = PyUnicode_InternFromString("decorator_list")) == NULL) return 0;
+ if ((state->defaults = PyUnicode_InternFromString("defaults")) == NULL) return 0;
+ if ((state->elt = PyUnicode_InternFromString("elt")) == NULL) return 0;
+ if ((state->elts = PyUnicode_InternFromString("elts")) == NULL) return 0;
+ if ((state->end_col_offset = PyUnicode_InternFromString("end_col_offset")) == NULL) return 0;
+ if ((state->end_lineno = PyUnicode_InternFromString("end_lineno")) == NULL) return 0;
+ if ((state->exc = PyUnicode_InternFromString("exc")) == NULL) return 0;
+ if ((state->finalbody = PyUnicode_InternFromString("finalbody")) == NULL) return 0;
+ if ((state->format_spec = PyUnicode_InternFromString("format_spec")) == NULL) return 0;
+ if ((state->func = PyUnicode_InternFromString("func")) == NULL) return 0;
+ if ((state->generators = PyUnicode_InternFromString("generators")) == NULL) return 0;
+ if ((state->handlers = PyUnicode_InternFromString("handlers")) == NULL) return 0;
+ if ((state->id = PyUnicode_InternFromString("id")) == NULL) return 0;
+ if ((state->ifs = PyUnicode_InternFromString("ifs")) == NULL) return 0;
+ if ((state->is_async = PyUnicode_InternFromString("is_async")) == NULL) return 0;
+ if ((state->items = PyUnicode_InternFromString("items")) == NULL) return 0;
+ if ((state->iter = PyUnicode_InternFromString("iter")) == NULL) return 0;
+ if ((state->key = PyUnicode_InternFromString("key")) == NULL) return 0;
+ if ((state->keys = PyUnicode_InternFromString("keys")) == NULL) return 0;
+ if ((state->keywords = PyUnicode_InternFromString("keywords")) == NULL) return 0;
+ if ((state->kind = PyUnicode_InternFromString("kind")) == NULL) return 0;
+ if ((state->kw_defaults = PyUnicode_InternFromString("kw_defaults")) == NULL) return 0;
+ if ((state->kwarg = PyUnicode_InternFromString("kwarg")) == NULL) return 0;
+ if ((state->kwonlyargs = PyUnicode_InternFromString("kwonlyargs")) == NULL) return 0;
+ if ((state->left = PyUnicode_InternFromString("left")) == NULL) return 0;
+ if ((state->level = PyUnicode_InternFromString("level")) == NULL) return 0;
+ if ((state->lineno = PyUnicode_InternFromString("lineno")) == NULL) return 0;
+ if ((state->lower = PyUnicode_InternFromString("lower")) == NULL) return 0;
+ if ((state->module = PyUnicode_InternFromString("module")) == NULL) return 0;
+ if ((state->msg = PyUnicode_InternFromString("msg")) == NULL) return 0;
+ if ((state->name = PyUnicode_InternFromString("name")) == NULL) return 0;
+ if ((state->names = PyUnicode_InternFromString("names")) == NULL) return 0;
+ if ((state->op = PyUnicode_InternFromString("op")) == NULL) return 0;
+ if ((state->operand = PyUnicode_InternFromString("operand")) == NULL) return 0;
+ if ((state->ops = PyUnicode_InternFromString("ops")) == NULL) return 0;
+ if ((state->optional_vars = PyUnicode_InternFromString("optional_vars")) == NULL) return 0;
+ if ((state->orelse = PyUnicode_InternFromString("orelse")) == NULL) return 0;
+ if ((state->posonlyargs = PyUnicode_InternFromString("posonlyargs")) == NULL) return 0;
+ if ((state->returns = PyUnicode_InternFromString("returns")) == NULL) return 0;
+ if ((state->right = PyUnicode_InternFromString("right")) == NULL) return 0;
+ if ((state->simple = PyUnicode_InternFromString("simple")) == NULL) return 0;
+ if ((state->slice = PyUnicode_InternFromString("slice")) == NULL) return 0;
+ if ((state->step = PyUnicode_InternFromString("step")) == NULL) return 0;
+ if ((state->tag = PyUnicode_InternFromString("tag")) == NULL) return 0;
+ if ((state->target = PyUnicode_InternFromString("target")) == NULL) return 0;
+ if ((state->targets = PyUnicode_InternFromString("targets")) == NULL) return 0;
+ if ((state->test = PyUnicode_InternFromString("test")) == NULL) return 0;
+ if ((state->type = PyUnicode_InternFromString("type")) == NULL) return 0;
+ if ((state->type_comment = PyUnicode_InternFromString("type_comment")) == NULL) return 0;
+ if ((state->type_ignores = PyUnicode_InternFromString("type_ignores")) == NULL) return 0;
+ if ((state->upper = PyUnicode_InternFromString("upper")) == NULL) return 0;
+ if ((state->value = PyUnicode_InternFromString("value")) == NULL) return 0;
+ if ((state->values = PyUnicode_InternFromString("values")) == NULL) return 0;
+ if ((state->vararg = PyUnicode_InternFromString("vararg")) == NULL) return 0;
+ return 1;
+};
+
+static PyObject* ast2obj_mod(astmodulestate *state, void*);
+static const char * const Module_fields[]={
+ "body",
+ "type_ignores",
+};
+static const char * const Interactive_fields[]={
+ "body",
+};
+static const char * const Expression_fields[]={
+ "body",
+};
+static const char * const FunctionType_fields[]={
+ "argtypes",
+ "returns",
+};
+static const char * const stmt_attributes[] = {
+ "lineno",
+ "col_offset",
+ "end_lineno",
+ "end_col_offset",
+};
+static PyObject* ast2obj_stmt(astmodulestate *state, void*);
+static const char * const FunctionDef_fields[]={
+ "name",
+ "args",
+ "body",
+ "decorator_list",
+ "returns",
+ "type_comment",
+};
+static const char * const AsyncFunctionDef_fields[]={
+ "name",
+ "args",
+ "body",
+ "decorator_list",
+ "returns",
+ "type_comment",
+};
+static const char * const ClassDef_fields[]={
+ "name",
+ "bases",
+ "keywords",
+ "body",
+ "decorator_list",
+};
+static const char * const Return_fields[]={
+ "value",
+};
+static const char * const Delete_fields[]={
+ "targets",
+};
+static const char * const Assign_fields[]={
+ "targets",
+ "value",
+ "type_comment",
+};
+static const char * const AugAssign_fields[]={
+ "target",
+ "op",
+ "value",
+};
+static const char * const AnnAssign_fields[]={
+ "target",
+ "annotation",
+ "value",
+ "simple",
+};
+static const char * const For_fields[]={
+ "target",
+ "iter",
+ "body",
+ "orelse",
+ "type_comment",
+};
+static const char * const AsyncFor_fields[]={
+ "target",
+ "iter",
+ "body",
+ "orelse",
+ "type_comment",
+};
+static const char * const While_fields[]={
+ "test",
+ "body",
+ "orelse",
+};
+static const char * const If_fields[]={
+ "test",
+ "body",
+ "orelse",
+};
+static const char * const With_fields[]={
+ "items",
+ "body",
+ "type_comment",
+};
+static const char * const AsyncWith_fields[]={
+ "items",
+ "body",
+ "type_comment",
+};
+static const char * const Raise_fields[]={
+ "exc",
+ "cause",
+};
+static const char * const Try_fields[]={
+ "body",
+ "handlers",
+ "orelse",
+ "finalbody",
+};
+static const char * const Assert_fields[]={
+ "test",
+ "msg",
+};
+static const char * const Import_fields[]={
+ "names",
+};
+static const char * const ImportFrom_fields[]={
+ "module",
+ "names",
+ "level",
+};
+static const char * const Global_fields[]={
+ "names",
+};
+static const char * const Nonlocal_fields[]={
+ "names",
+};
+static const char * const Expr_fields[]={
+ "value",
+};
+static const char * const expr_attributes[] = {
+ "lineno",
+ "col_offset",
+ "end_lineno",
+ "end_col_offset",
+};
+static PyObject* ast2obj_expr(astmodulestate *state, void*);
+static const char * const BoolOp_fields[]={
+ "op",
+ "values",
+};
+static const char * const NamedExpr_fields[]={
+ "target",
+ "value",
+};
+static const char * const BinOp_fields[]={
+ "left",
+ "op",
+ "right",
+};
+static const char * const UnaryOp_fields[]={
+ "op",
+ "operand",
+};
+static const char * const Lambda_fields[]={
+ "args",
+ "body",
+};
+static const char * const IfExp_fields[]={
+ "test",
+ "body",
+ "orelse",
+};
+static const char * const Dict_fields[]={
+ "keys",
+ "values",
+};
+static const char * const Set_fields[]={
+ "elts",
+};
+static const char * const ListComp_fields[]={
+ "elt",
+ "generators",
+};
+static const char * const SetComp_fields[]={
+ "elt",
+ "generators",
+};
+static const char * const DictComp_fields[]={
+ "key",
+ "value",
+ "generators",
+};
+static const char * const GeneratorExp_fields[]={
+ "elt",
+ "generators",
+};
+static const char * const Await_fields[]={
+ "value",
+};
+static const char * const Yield_fields[]={
+ "value",
+};
+static const char * const YieldFrom_fields[]={
+ "value",
+};
+static const char * const Compare_fields[]={
+ "left",
+ "ops",
+ "comparators",
+};
+static const char * const Call_fields[]={
+ "func",
+ "args",
+ "keywords",
+};
+static const char * const FormattedValue_fields[]={
+ "value",
+ "conversion",
+ "format_spec",
+};
+static const char * const JoinedStr_fields[]={
+ "values",
+};
+static const char * const Constant_fields[]={
+ "value",
+ "kind",
+};
+static const char * const Attribute_fields[]={
+ "value",
+ "attr",
+ "ctx",
+};
+static const char * const Subscript_fields[]={
+ "value",
+ "slice",
+ "ctx",
+};
+static const char * const Starred_fields[]={
+ "value",
+ "ctx",
+};
+static const char * const Name_fields[]={
+ "id",
+ "ctx",
+};
+static const char * const List_fields[]={
+ "elts",
+ "ctx",
+};
+static const char * const Tuple_fields[]={
+ "elts",
+ "ctx",
+};
+static const char * const Slice_fields[]={
+ "lower",
+ "upper",
+ "step",
+};
+static PyObject* ast2obj_expr_context(astmodulestate *state, expr_context_ty);
+static PyObject* ast2obj_boolop(astmodulestate *state, boolop_ty);
+static PyObject* ast2obj_operator(astmodulestate *state, operator_ty);
+static PyObject* ast2obj_unaryop(astmodulestate *state, unaryop_ty);
+static PyObject* ast2obj_cmpop(astmodulestate *state, cmpop_ty);
+static PyObject* ast2obj_comprehension(astmodulestate *state, void*);
+static const char * const comprehension_fields[]={
+ "target",
+ "iter",
+ "ifs",
+ "is_async",
+};
+static const char * const excepthandler_attributes[] = {
+ "lineno",
+ "col_offset",
+ "end_lineno",
+ "end_col_offset",
+};
+static PyObject* ast2obj_excepthandler(astmodulestate *state, void*);
+static const char * const ExceptHandler_fields[]={
+ "type",
+ "name",
+ "body",
+};
+static PyObject* ast2obj_arguments(astmodulestate *state, void*);
+static const char * const arguments_fields[]={
+ "posonlyargs",
+ "args",
+ "vararg",
+ "kwonlyargs",
+ "kw_defaults",
+ "kwarg",
+ "defaults",
+};
+static PyObject* ast2obj_arg(astmodulestate *state, void*);
+static const char * const arg_attributes[] = {
+ "lineno",
+ "col_offset",
+ "end_lineno",
+ "end_col_offset",
+};
+static const char * const arg_fields[]={
+ "arg",
+ "annotation",
+ "type_comment",
+};
+static PyObject* ast2obj_keyword(astmodulestate *state, void*);
+static const char * const keyword_attributes[] = {
+ "lineno",
+ "col_offset",
+ "end_lineno",
+ "end_col_offset",
+};
+static const char * const keyword_fields[]={
+ "arg",
+ "value",
+};
+static PyObject* ast2obj_alias(astmodulestate *state, void*);
+static const char * const alias_fields[]={
+ "name",
+ "asname",
+};
+static PyObject* ast2obj_withitem(astmodulestate *state, void*);
+static const char * const withitem_fields[]={
+ "context_expr",
+ "optional_vars",
+};
+static PyObject* ast2obj_type_ignore(astmodulestate *state, void*);
+static const char * const TypeIgnore_fields[]={
+ "lineno",
+ "tag",
+};
+
+
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *dict;
+} AST_object;
+
+static void
+ast_dealloc(AST_object *self)
+{
+ /* bpo-31095: UnTrack is needed before calling any callbacks */
+ PyTypeObject *tp = Py_TYPE(self);
+ PyObject_GC_UnTrack(self);
+ Py_CLEAR(self->dict);
+ freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
+ assert(free_func != NULL);
+ free_func(self);
+ Py_DECREF(tp);
+}
+
+static int
+ast_traverse(AST_object *self, visitproc visit, void *arg)
+{
+ Py_VISIT(Py_TYPE(self));
+ Py_VISIT(self->dict);
+ return 0;
+}
+
+static int
+ast_clear(AST_object *self)
+{
+ Py_CLEAR(self->dict);
+ return 0;
+}
+
+static int
+ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
+{
+ astmodulestate *state = get_global_ast_state();
+ if (state == NULL) {
+ return -1;
+ }
+
+ Py_ssize_t i, numfields = 0;
+ int res = -1;
+ PyObject *key, *value, *fields;
+ if (_PyObject_LookupAttr((PyObject*)Py_TYPE(self), state->_fields, &fields) < 0) {
+ goto cleanup;
+ }
+ if (fields) {
+ numfields = PySequence_Size(fields);
+ if (numfields == -1) {
+ goto cleanup;
+ }
+ }
+
+ res = 0; /* if no error occurs, this stays 0 to the end */
+ if (numfields < PyTuple_GET_SIZE(args)) {
+ PyErr_Format(PyExc_TypeError, "%.400s constructor takes at most "
+ "%zd positional argument%s",
+ _PyType_Name(Py_TYPE(self)),
+ numfields, numfields == 1 ? "" : "s");
+ res = -1;
+ goto cleanup;
+ }
+ for (i = 0; i < PyTuple_GET_SIZE(args); i++) {
+ /* cannot be reached when fields is NULL */
+ PyObject *name = PySequence_GetItem(fields, i);
+ if (!name) {
+ res = -1;
+ goto cleanup;
+ }
+ res = PyObject_SetAttr(self, name, PyTuple_GET_ITEM(args, i));
+ Py_DECREF(name);
+ if (res < 0) {
+ goto cleanup;
+ }
+ }
+ if (kw) {
+ i = 0; /* needed by PyDict_Next */
+ while (PyDict_Next(kw, &i, &key, &value)) {
+ int contains = PySequence_Contains(fields, key);
+ if (contains == -1) {
+ res = -1;
+ goto cleanup;
+ } else if (contains == 1) {
+ Py_ssize_t p = PySequence_Index(fields, key);
+ if (p == -1) {
+ res = -1;
+ goto cleanup;
+ }
+ if (p < PyTuple_GET_SIZE(args)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.400s got multiple values for argument '%U'",
+ Py_TYPE(self)->tp_name, key);
+ res = -1;
+ goto cleanup;
+ }
+ }
+ res = PyObject_SetAttr(self, key, value);
+ if (res < 0) {
+ goto cleanup;
+ }
+ }
+ }
+ cleanup:
+ Py_XDECREF(fields);
+ return res;
+}
+
+/* Pickling support */
+static PyObject *
+ast_type_reduce(PyObject *self, PyObject *unused)
+{
+ astmodulestate *state = get_global_ast_state();
+ if (state == NULL) {
+ return NULL;
+ }
+
+ PyObject *dict;
+ if (_PyObject_LookupAttr(self, state->__dict__, &dict) < 0) {
+ return NULL;
+ }
+ if (dict) {
+ return Py_BuildValue("O()N", Py_TYPE(self), dict);
+ }
+ return Py_BuildValue("O()", Py_TYPE(self));
+}
+
+static PyMemberDef ast_type_members[] = {
+ {"__dictoffset__", T_PYSSIZET, offsetof(AST_object, dict), READONLY},
+ {NULL} /* Sentinel */
+};
+
+static PyMethodDef ast_type_methods[] = {
+ {"__reduce__", ast_type_reduce, METH_NOARGS, NULL},
+ {NULL}
+};
+
+static PyGetSetDef ast_type_getsets[] = {
+ {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
+ {NULL}
+};
+
+static PyType_Slot AST_type_slots[] = {
+ {Py_tp_dealloc, ast_dealloc},
+ {Py_tp_getattro, PyObject_GenericGetAttr},
+ {Py_tp_setattro, PyObject_GenericSetAttr},
+ {Py_tp_traverse, ast_traverse},
+ {Py_tp_clear, ast_clear},
+ {Py_tp_members, ast_type_members},
+ {Py_tp_methods, ast_type_methods},
+ {Py_tp_getset, ast_type_getsets},
+ {Py_tp_init, ast_type_init},
+ {Py_tp_alloc, PyType_GenericAlloc},
+ {Py_tp_new, PyType_GenericNew},
+ {Py_tp_free, PyObject_GC_Del},
+ {0, 0},
+};
+
+static PyType_Spec AST_type_spec = {
+ "ast.AST",
+ sizeof(AST_object),
+ 0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+ AST_type_slots
+};
+
+static PyObject *
+make_type(astmodulestate *state, const char *type, PyObject* base,
+ const char* const* fields, int num_fields, const char *doc)
+{
+ PyObject *fnames, *result;
+ int i;
+ fnames = PyTuple_New(num_fields);
+ if (!fnames) return NULL;
+ for (i = 0; i < num_fields; i++) {
+ PyObject *field = PyUnicode_InternFromString(fields[i]);
+ if (!field) {
+ Py_DECREF(fnames);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(fnames, i, field);
+ }
+ result = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){OOOOOs}",
+ type, base,
+ state->_fields, fnames,
+ state->__module__,
+ state->ast,
+ state->__doc__, doc);
+ Py_DECREF(fnames);
+ return result;
+}
+
+static int
+add_attributes(astmodulestate *state, PyObject *type, const char * const *attrs, int num_fields)
+{
+ int i, result;
+ PyObject *s, *l = PyTuple_New(num_fields);
+ if (!l)
+ return 0;
+ for (i = 0; i < num_fields; i++) {
+ s = PyUnicode_InternFromString(attrs[i]);
+ if (!s) {
+ Py_DECREF(l);
+ return 0;
+ }
+ PyTuple_SET_ITEM(l, i, s);
+ }
+ result = PyObject_SetAttr(type, state->_attributes, l) >= 0;
+ Py_DECREF(l);
+ return result;
+}
+
+/* Conversion AST -> Python */
+
+static PyObject* ast2obj_list(astmodulestate *state, asdl_seq *seq, PyObject* (*func)(astmodulestate *state, void*))
+{
+ Py_ssize_t i, n = asdl_seq_LEN(seq);
+ PyObject *result = PyList_New(n);
+ PyObject *value;
+ if (!result)
+ return NULL;
+ for (i = 0; i < n; i++) {
+ value = func(state, asdl_seq_GET(seq, i));
+ if (!value) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ PyList_SET_ITEM(result, i, value);
+ }
+ return result;
+}
+
+static PyObject* ast2obj_object(astmodulestate *Py_UNUSED(state), void *o)
+{
+ if (!o)
+ o = Py_None;
+ Py_INCREF((PyObject*)o);
+ return (PyObject*)o;
+}
+#define ast2obj_constant ast2obj_object
+#define ast2obj_identifier ast2obj_object
+#define ast2obj_string ast2obj_object
+
+static PyObject* ast2obj_int(astmodulestate *Py_UNUSED(state), long b)
+{
+ return PyLong_FromLong(b);
+}
+
+/* Conversion Python -> AST */
+
+static int obj2ast_object(astmodulestate *Py_UNUSED(state), PyObject* obj, PyObject** out, PyArena* arena)
+{
+ if (obj == Py_None)
+ obj = NULL;
+ if (obj) {
+ if (PyArena_AddPyObject(arena, obj) < 0) {
+ *out = NULL;
+ return -1;
+ }
+ Py_INCREF(obj);
+ }
+ *out = obj;
+ return 0;
+}
+
+static int obj2ast_constant(astmodulestate *Py_UNUSED(state), PyObject* obj, PyObject** out, PyArena* arena)
+{
+ if (PyArena_AddPyObject(arena, obj) < 0) {
+ *out = NULL;
+ return -1;
+ }
+ Py_INCREF(obj);
+ *out = obj;
+ return 0;
+}
+
+static int obj2ast_identifier(astmodulestate *state, PyObject* obj, PyObject** out, PyArena* arena)
+{
+ if (!PyUnicode_CheckExact(obj) && obj != Py_None) {
+ PyErr_SetString(PyExc_TypeError, "AST identifier must be of type str");
+ return 1;
+ }
+ return obj2ast_object(state, obj, out, arena);
+}
+
+static int obj2ast_string(astmodulestate *state, PyObject* obj, PyObject** out, PyArena* arena)
+{
+ if (!PyUnicode_CheckExact(obj) && !PyBytes_CheckExact(obj)) {
+ PyErr_SetString(PyExc_TypeError, "AST string must be of type str");
+ return 1;
+ }
+ return obj2ast_object(state, obj, out, arena);
+}
+
+static int obj2ast_int(astmodulestate* Py_UNUSED(state), PyObject* obj, int* out, PyArena* arena)
+{
+ int i;
+ if (!PyLong_Check(obj)) {
+ PyErr_Format(PyExc_ValueError, "invalid integer value: %R", obj);
+ return 1;
+ }
+
+ i = _PyLong_AsInt(obj);
+ if (i == -1 && PyErr_Occurred())
+ return 1;
+ *out = i;
+ return 0;
+}
+
+static int add_ast_fields(astmodulestate *state)
+{
+ PyObject *empty_tuple;
+ empty_tuple = PyTuple_New(0);
+ if (!empty_tuple ||
+ PyObject_SetAttrString(state->AST_type, "_fields", empty_tuple) < 0 ||
+ PyObject_SetAttrString(state->AST_type, "_attributes", empty_tuple) < 0) {
+ Py_XDECREF(empty_tuple);
+ return -1;
+ }
+ Py_DECREF(empty_tuple);
+ return 0;
+}
+
+
+static int init_types(astmodulestate *state)
+{
+ if (state->initialized) return 1;
+ if (init_identifiers(state) < 0) return 0;
+ state->AST_type = PyType_FromSpec(&AST_type_spec);
+ if (!state->AST_type) return 0;
+ if (add_ast_fields(state) < 0) return 0;
+ state->mod_type = make_type(state, "mod", state->AST_type, NULL, 0,
+ "mod = Module(stmt* body, type_ignore* type_ignores)\n"
+ " | Interactive(stmt* body)\n"
+ " | Expression(expr body)\n"
+ " | FunctionType(expr* argtypes, expr returns)");
+ if (!state->mod_type) return 0;
+ if (!add_attributes(state, state->mod_type, NULL, 0)) return 0;
+ state->Module_type = make_type(state, "Module", state->mod_type,
+ Module_fields, 2,
+ "Module(stmt* body, type_ignore* type_ignores)");
+ if (!state->Module_type) return 0;
+ state->Interactive_type = make_type(state, "Interactive", state->mod_type,
+ Interactive_fields, 1,
+ "Interactive(stmt* body)");
+ if (!state->Interactive_type) return 0;
+ state->Expression_type = make_type(state, "Expression", state->mod_type,
+ Expression_fields, 1,
+ "Expression(expr body)");
+ if (!state->Expression_type) return 0;
+ state->FunctionType_type = make_type(state, "FunctionType",
+ state->mod_type, FunctionType_fields,
+ 2,
+ "FunctionType(expr* argtypes, expr returns)");
+ if (!state->FunctionType_type) return 0;
+ state->stmt_type = make_type(state, "stmt", state->AST_type, NULL, 0,
+ "stmt = FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)\n"
+ " | AsyncFunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)\n"
+ " | ClassDef(identifier name, expr* bases, keyword* keywords, stmt* body, expr* decorator_list)\n"
+ " | Return(expr? value)\n"
+ " | Delete(expr* targets)\n"
+ " | Assign(expr* targets, expr value, string? type_comment)\n"
+ " | AugAssign(expr target, operator op, expr value)\n"
+ " | AnnAssign(expr target, expr annotation, expr? value, int simple)\n"
+ " | For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)\n"
+ " | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)\n"
+ " | While(expr test, stmt* body, stmt* orelse)\n"
+ " | If(expr test, stmt* body, stmt* orelse)\n"
+ " | With(withitem* items, stmt* body, string? type_comment)\n"
+ " | AsyncWith(withitem* items, stmt* body, string? type_comment)\n"
+ " | Raise(expr? exc, expr? cause)\n"
+ " | Try(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"
+ " | Global(identifier* names)\n"
+ " | Nonlocal(identifier* names)\n"
+ " | Expr(expr value)\n"
+ " | Pass\n"
+ " | Break\n"
+ " | Continue");
+ if (!state->stmt_type) return 0;
+ if (!add_attributes(state, state->stmt_type, stmt_attributes, 4)) return 0;
+ if (PyObject_SetAttr(state->stmt_type, state->end_lineno, Py_None) == -1)
+ return 0;
+ if (PyObject_SetAttr(state->stmt_type, state->end_col_offset, Py_None) ==
+ -1)
+ return 0;
+ state->FunctionDef_type = make_type(state, "FunctionDef", state->stmt_type,
+ FunctionDef_fields, 6,
+ "FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)");
+ if (!state->FunctionDef_type) return 0;
+ if (PyObject_SetAttr(state->FunctionDef_type, state->returns, Py_None) ==
+ -1)
+ return 0;
+ if (PyObject_SetAttr(state->FunctionDef_type, state->type_comment, Py_None)
+ == -1)
+ return 0;
+ state->AsyncFunctionDef_type = make_type(state, "AsyncFunctionDef",
+ state->stmt_type,
+ AsyncFunctionDef_fields, 6,
+ "AsyncFunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)");
+ if (!state->AsyncFunctionDef_type) return 0;
+ if (PyObject_SetAttr(state->AsyncFunctionDef_type, state->returns, Py_None)
+ == -1)
+ return 0;
+ if (PyObject_SetAttr(state->AsyncFunctionDef_type, state->type_comment,
+ Py_None) == -1)
+ return 0;
+ state->ClassDef_type = make_type(state, "ClassDef", state->stmt_type,
+ ClassDef_fields, 5,
+ "ClassDef(identifier name, expr* bases, keyword* keywords, stmt* body, expr* decorator_list)");
+ if (!state->ClassDef_type) return 0;
+ state->Return_type = make_type(state, "Return", state->stmt_type,
+ Return_fields, 1,
+ "Return(expr? value)");
+ if (!state->Return_type) return 0;
+ if (PyObject_SetAttr(state->Return_type, state->value, Py_None) == -1)
+ return 0;
+ state->Delete_type = make_type(state, "Delete", state->stmt_type,
+ Delete_fields, 1,
+ "Delete(expr* targets)");
+ if (!state->Delete_type) return 0;
+ state->Assign_type = make_type(state, "Assign", state->stmt_type,
+ Assign_fields, 3,
+ "Assign(expr* targets, expr value, string? type_comment)");
+ if (!state->Assign_type) return 0;
+ if (PyObject_SetAttr(state->Assign_type, state->type_comment, Py_None) ==
+ -1)
+ return 0;
+ state->AugAssign_type = make_type(state, "AugAssign", state->stmt_type,
+ AugAssign_fields, 3,
+ "AugAssign(expr target, operator op, expr value)");
+ if (!state->AugAssign_type) return 0;
+ state->AnnAssign_type = make_type(state, "AnnAssign", state->stmt_type,
+ AnnAssign_fields, 4,
+ "AnnAssign(expr target, expr annotation, expr? value, int simple)");
+ if (!state->AnnAssign_type) return 0;
+ if (PyObject_SetAttr(state->AnnAssign_type, state->value, Py_None) == -1)
+ return 0;
+ state->For_type = make_type(state, "For", state->stmt_type, For_fields, 5,
+ "For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)");
+ if (!state->For_type) return 0;
+ if (PyObject_SetAttr(state->For_type, state->type_comment, Py_None) == -1)
+ return 0;
+ state->AsyncFor_type = make_type(state, "AsyncFor", state->stmt_type,
+ AsyncFor_fields, 5,
+ "AsyncFor(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)");
+ if (!state->AsyncFor_type) return 0;
+ if (PyObject_SetAttr(state->AsyncFor_type, state->type_comment, Py_None) ==
+ -1)
+ return 0;
+ state->While_type = make_type(state, "While", state->stmt_type,
+ While_fields, 3,
+ "While(expr test, stmt* body, stmt* orelse)");
+ if (!state->While_type) return 0;
+ state->If_type = make_type(state, "If", state->stmt_type, If_fields, 3,
+ "If(expr test, stmt* body, stmt* orelse)");
+ if (!state->If_type) return 0;
+ state->With_type = make_type(state, "With", state->stmt_type, With_fields,
+ 3,
+ "With(withitem* items, stmt* body, string? type_comment)");
+ if (!state->With_type) return 0;
+ if (PyObject_SetAttr(state->With_type, state->type_comment, Py_None) == -1)
+ return 0;
+ state->AsyncWith_type = make_type(state, "AsyncWith", state->stmt_type,
+ AsyncWith_fields, 3,
+ "AsyncWith(withitem* items, stmt* body, string? type_comment)");
+ if (!state->AsyncWith_type) return 0;
+ if (PyObject_SetAttr(state->AsyncWith_type, state->type_comment, Py_None)
+ == -1)
+ return 0;
+ state->Raise_type = make_type(state, "Raise", state->stmt_type,
+ Raise_fields, 2,
+ "Raise(expr? exc, expr? cause)");
+ if (!state->Raise_type) return 0;
+ if (PyObject_SetAttr(state->Raise_type, state->exc, Py_None) == -1)
+ return 0;
+ if (PyObject_SetAttr(state->Raise_type, state->cause, Py_None) == -1)
+ return 0;
+ state->Try_type = make_type(state, "Try", state->stmt_type, Try_fields, 4,
+ "Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)");
+ if (!state->Try_type) return 0;
+ state->Assert_type = make_type(state, "Assert", state->stmt_type,
+ Assert_fields, 2,
+ "Assert(expr test, expr? msg)");
+ if (!state->Assert_type) return 0;
+ if (PyObject_SetAttr(state->Assert_type, state->msg, Py_None) == -1)
+ return 0;
+ state->Import_type = make_type(state, "Import", state->stmt_type,
+ Import_fields, 1,
+ "Import(alias* names)");
+ if (!state->Import_type) return 0;
+ state->ImportFrom_type = make_type(state, "ImportFrom", state->stmt_type,
+ ImportFrom_fields, 3,
+ "ImportFrom(identifier? module, alias* names, int? level)");
+ if (!state->ImportFrom_type) return 0;
+ if (PyObject_SetAttr(state->ImportFrom_type, state->module, Py_None) == -1)
+ return 0;
+ if (PyObject_SetAttr(state->ImportFrom_type, state->level, Py_None) == -1)
+ return 0;
+ state->Global_type = make_type(state, "Global", state->stmt_type,
+ Global_fields, 1,
+ "Global(identifier* names)");
+ if (!state->Global_type) return 0;
+ state->Nonlocal_type = make_type(state, "Nonlocal", state->stmt_type,
+ Nonlocal_fields, 1,
+ "Nonlocal(identifier* names)");
+ if (!state->Nonlocal_type) return 0;
+ state->Expr_type = make_type(state, "Expr", state->stmt_type, Expr_fields,
+ 1,
+ "Expr(expr value)");
+ if (!state->Expr_type) return 0;
+ state->Pass_type = make_type(state, "Pass", state->stmt_type, NULL, 0,
+ "Pass");
+ if (!state->Pass_type) return 0;
+ state->Break_type = make_type(state, "Break", state->stmt_type, NULL, 0,
+ "Break");
+ if (!state->Break_type) return 0;
+ state->Continue_type = make_type(state, "Continue", state->stmt_type, NULL,
+ 0,
+ "Continue");
+ if (!state->Continue_type) return 0;
+ state->expr_type = make_type(state, "expr", state->AST_type, NULL, 0,
+ "expr = BoolOp(boolop op, expr* values)\n"
+ " | NamedExpr(expr target, expr value)\n"
+ " | BinOp(expr left, operator op, expr right)\n"
+ " | UnaryOp(unaryop op, expr operand)\n"
+ " | Lambda(arguments args, expr body)\n"
+ " | IfExp(expr test, expr body, expr orelse)\n"
+ " | Dict(expr* keys, expr* values)\n"
+ " | Set(expr* elts)\n"
+ " | ListComp(expr elt, comprehension* generators)\n"
+ " | SetComp(expr elt, comprehension* generators)\n"
+ " | DictComp(expr key, expr value, comprehension* generators)\n"
+ " | GeneratorExp(expr elt, comprehension* generators)\n"
+ " | Await(expr value)\n"
+ " | Yield(expr? value)\n"
+ " | YieldFrom(expr value)\n"
+ " | Compare(expr left, cmpop* ops, expr* comparators)\n"
+ " | Call(expr func, expr* args, keyword* keywords)\n"
+ " | FormattedValue(expr value, int? conversion, expr? format_spec)\n"
+ " | JoinedStr(expr* values)\n"
+ " | Constant(constant value, string? kind)\n"
+ " | Attribute(expr value, identifier attr, expr_context ctx)\n"
+ " | Subscript(expr value, expr slice, expr_context ctx)\n"
+ " | Starred(expr value, expr_context ctx)\n"
+ " | Name(identifier id, expr_context ctx)\n"
+ " | List(expr* elts, expr_context ctx)\n"
+ " | Tuple(expr* elts, expr_context ctx)\n"
+ " | Slice(expr? lower, expr? upper, expr? step)");
+ if (!state->expr_type) return 0;
+ if (!add_attributes(state, state->expr_type, expr_attributes, 4)) return 0;
+ if (PyObject_SetAttr(state->expr_type, state->end_lineno, Py_None) == -1)
+ return 0;
+ if (PyObject_SetAttr(state->expr_type, state->end_col_offset, Py_None) ==
+ -1)
+ return 0;
+ state->BoolOp_type = make_type(state, "BoolOp", state->expr_type,
+ BoolOp_fields, 2,
+ "BoolOp(boolop op, expr* values)");
+ if (!state->BoolOp_type) return 0;
+ state->NamedExpr_type = make_type(state, "NamedExpr", state->expr_type,
+ NamedExpr_fields, 2,
+ "NamedExpr(expr target, expr value)");
+ if (!state->NamedExpr_type) return 0;
+ state->BinOp_type = make_type(state, "BinOp", state->expr_type,
+ BinOp_fields, 3,
+ "BinOp(expr left, operator op, expr right)");
+ if (!state->BinOp_type) return 0;
+ state->UnaryOp_type = make_type(state, "UnaryOp", state->expr_type,
+ UnaryOp_fields, 2,
+ "UnaryOp(unaryop op, expr operand)");
+ if (!state->UnaryOp_type) return 0;
+ state->Lambda_type = make_type(state, "Lambda", state->expr_type,
+ Lambda_fields, 2,
+ "Lambda(arguments args, expr body)");
+ if (!state->Lambda_type) return 0;
+ state->IfExp_type = make_type(state, "IfExp", state->expr_type,
+ IfExp_fields, 3,
+ "IfExp(expr test, expr body, expr orelse)");
+ if (!state->IfExp_type) return 0;
+ state->Dict_type = make_type(state, "Dict", state->expr_type, Dict_fields,
+ 2,
+ "Dict(expr* keys, expr* values)");
+ if (!state->Dict_type) return 0;
+ state->Set_type = make_type(state, "Set", state->expr_type, Set_fields, 1,
+ "Set(expr* elts)");
+ if (!state->Set_type) return 0;
+ state->ListComp_type = make_type(state, "ListComp", state->expr_type,
+ ListComp_fields, 2,
+ "ListComp(expr elt, comprehension* generators)");
+ if (!state->ListComp_type) return 0;
+ state->SetComp_type = make_type(state, "SetComp", state->expr_type,
+ SetComp_fields, 2,
+ "SetComp(expr elt, comprehension* generators)");
+ if (!state->SetComp_type) return 0;
+ state->DictComp_type = make_type(state, "DictComp", state->expr_type,
+ DictComp_fields, 3,
+ "DictComp(expr key, expr value, comprehension* generators)");
+ if (!state->DictComp_type) return 0;
+ state->GeneratorExp_type = make_type(state, "GeneratorExp",
+ state->expr_type, GeneratorExp_fields,
+ 2,
+ "GeneratorExp(expr elt, comprehension* generators)");
+ if (!state->GeneratorExp_type) return 0;
+ state->Await_type = make_type(state, "Await", state->expr_type,
+ Await_fields, 1,
+ "Await(expr value)");
+ if (!state->Await_type) return 0;
+ state->Yield_type = make_type(state, "Yield", state->expr_type,
+ Yield_fields, 1,
+ "Yield(expr? value)");
+ if (!state->Yield_type) return 0;
+ if (PyObject_SetAttr(state->Yield_type, state->value, Py_None) == -1)
+ return 0;
+ state->YieldFrom_type = make_type(state, "YieldFrom", state->expr_type,
+ YieldFrom_fields, 1,
+ "YieldFrom(expr value)");
+ if (!state->YieldFrom_type) return 0;
+ state->Compare_type = make_type(state, "Compare", state->expr_type,
+ Compare_fields, 3,
+ "Compare(expr left, cmpop* ops, expr* comparators)");
+ if (!state->Compare_type) return 0;
+ state->Call_type = make_type(state, "Call", state->expr_type, Call_fields,
+ 3,
+ "Call(expr func, expr* args, keyword* keywords)");
+ if (!state->Call_type) return 0;
+ state->FormattedValue_type = make_type(state, "FormattedValue",
+ state->expr_type,
+ FormattedValue_fields, 3,
+ "FormattedValue(expr value, int? conversion, expr? format_spec)");
+ if (!state->FormattedValue_type) return 0;
+ if (PyObject_SetAttr(state->FormattedValue_type, state->conversion,
+ Py_None) == -1)
+ return 0;
+ if (PyObject_SetAttr(state->FormattedValue_type, state->format_spec,
+ Py_None) == -1)
+ return 0;
+ state->JoinedStr_type = make_type(state, "JoinedStr", state->expr_type,
+ JoinedStr_fields, 1,
+ "JoinedStr(expr* values)");
+ if (!state->JoinedStr_type) return 0;
+ state->Constant_type = make_type(state, "Constant", state->expr_type,
+ Constant_fields, 2,
+ "Constant(constant value, string? kind)");
+ if (!state->Constant_type) return 0;
+ if (PyObject_SetAttr(state->Constant_type, state->kind, Py_None) == -1)
+ return 0;
+ state->Attribute_type = make_type(state, "Attribute", state->expr_type,
+ Attribute_fields, 3,
+ "Attribute(expr value, identifier attr, expr_context ctx)");
+ if (!state->Attribute_type) return 0;
+ state->Subscript_type = make_type(state, "Subscript", state->expr_type,
+ Subscript_fields, 3,
+ "Subscript(expr value, expr slice, expr_context ctx)");
+ if (!state->Subscript_type) return 0;
+ state->Starred_type = make_type(state, "Starred", state->expr_type,
+ Starred_fields, 2,
+ "Starred(expr value, expr_context ctx)");
+ if (!state->Starred_type) return 0;
+ state->Name_type = make_type(state, "Name", state->expr_type, Name_fields,
+ 2,
+ "Name(identifier id, expr_context ctx)");
+ if (!state->Name_type) return 0;
+ state->List_type = make_type(state, "List", state->expr_type, List_fields,
+ 2,
+ "List(expr* elts, expr_context ctx)");
+ if (!state->List_type) return 0;
+ state->Tuple_type = make_type(state, "Tuple", state->expr_type,
+ Tuple_fields, 2,
+ "Tuple(expr* elts, expr_context ctx)");
+ if (!state->Tuple_type) return 0;
+ state->Slice_type = make_type(state, "Slice", state->expr_type,
+ Slice_fields, 3,
+ "Slice(expr? lower, expr? upper, expr? step)");
+ if (!state->Slice_type) return 0;
+ if (PyObject_SetAttr(state->Slice_type, state->lower, Py_None) == -1)
+ return 0;
+ if (PyObject_SetAttr(state->Slice_type, state->upper, Py_None) == -1)
+ return 0;
+ if (PyObject_SetAttr(state->Slice_type, state->step, Py_None) == -1)
+ return 0;
+ state->expr_context_type = make_type(state, "expr_context",
+ state->AST_type, NULL, 0,
+ "expr_context = Load | Store | Del");
+ if (!state->expr_context_type) return 0;
+ if (!add_attributes(state, state->expr_context_type, NULL, 0)) return 0;
+ state->Load_type = make_type(state, "Load", state->expr_context_type, NULL,
+ 0,
+ "Load");
+ if (!state->Load_type) return 0;
+ state->Load_singleton = PyType_GenericNew((PyTypeObject *)state->Load_type,
+ NULL, NULL);
+ if (!state->Load_singleton) return 0;
+ state->Store_type = make_type(state, "Store", state->expr_context_type,
+ NULL, 0,
+ "Store");
+ if (!state->Store_type) return 0;
+ state->Store_singleton = PyType_GenericNew((PyTypeObject
+ *)state->Store_type, NULL, NULL);
+ if (!state->Store_singleton) return 0;
+ state->Del_type = make_type(state, "Del", state->expr_context_type, NULL, 0,
+ "Del");
+ if (!state->Del_type) return 0;
+ state->Del_singleton = PyType_GenericNew((PyTypeObject *)state->Del_type,
+ NULL, NULL);
+ if (!state->Del_singleton) return 0;
+ state->boolop_type = make_type(state, "boolop", state->AST_type, NULL, 0,
+ "boolop = And | Or");
+ if (!state->boolop_type) return 0;
+ if (!add_attributes(state, state->boolop_type, NULL, 0)) return 0;
+ state->And_type = make_type(state, "And", state->boolop_type, NULL, 0,
+ "And");
+ if (!state->And_type) return 0;
+ state->And_singleton = PyType_GenericNew((PyTypeObject *)state->And_type,
+ NULL, NULL);
+ if (!state->And_singleton) return 0;
+ state->Or_type = make_type(state, "Or", state->boolop_type, NULL, 0,
+ "Or");
+ if (!state->Or_type) return 0;
+ state->Or_singleton = PyType_GenericNew((PyTypeObject *)state->Or_type,
+ NULL, NULL);
+ if (!state->Or_singleton) return 0;
+ state->operator_type = make_type(state, "operator", state->AST_type, NULL,
+ 0,
+ "operator = Add | Sub | Mult | MatMult | Div | Mod | Pow | LShift | RShift | BitOr | BitXor | BitAnd | FloorDiv");
+ if (!state->operator_type) return 0;
+ if (!add_attributes(state, state->operator_type, NULL, 0)) return 0;
+ state->Add_type = make_type(state, "Add", state->operator_type, NULL, 0,
+ "Add");
+ if (!state->Add_type) return 0;
+ state->Add_singleton = PyType_GenericNew((PyTypeObject *)state->Add_type,
+ NULL, NULL);
+ if (!state->Add_singleton) return 0;
+ state->Sub_type = make_type(state, "Sub", state->operator_type, NULL, 0,
+ "Sub");
+ if (!state->Sub_type) return 0;
+ state->Sub_singleton = PyType_GenericNew((PyTypeObject *)state->Sub_type,
+ NULL, NULL);
+ if (!state->Sub_singleton) return 0;
+ state->Mult_type = make_type(state, "Mult", state->operator_type, NULL, 0,
+ "Mult");
+ if (!state->Mult_type) return 0;
+ state->Mult_singleton = PyType_GenericNew((PyTypeObject *)state->Mult_type,
+ NULL, NULL);
+ if (!state->Mult_singleton) return 0;
+ state->MatMult_type = make_type(state, "MatMult", state->operator_type,
+ NULL, 0,
+ "MatMult");
+ if (!state->MatMult_type) return 0;
+ state->MatMult_singleton = PyType_GenericNew((PyTypeObject
+ *)state->MatMult_type, NULL,
+ NULL);
+ if (!state->MatMult_singleton) return 0;
+ state->Div_type = make_type(state, "Div", state->operator_type, NULL, 0,
+ "Div");
+ if (!state->Div_type) return 0;
+ state->Div_singleton = PyType_GenericNew((PyTypeObject *)state->Div_type,
+ NULL, NULL);
+ if (!state->Div_singleton) return 0;
+ state->Mod_type = make_type(state, "Mod", state->operator_type, NULL, 0,
+ "Mod");
+ if (!state->Mod_type) return 0;
+ state->Mod_singleton = PyType_GenericNew((PyTypeObject *)state->Mod_type,
+ NULL, NULL);
+ if (!state->Mod_singleton) return 0;
+ state->Pow_type = make_type(state, "Pow", state->operator_type, NULL, 0,
+ "Pow");
+ if (!state->Pow_type) return 0;
+ state->Pow_singleton = PyType_GenericNew((PyTypeObject *)state->Pow_type,
+ NULL, NULL);
+ if (!state->Pow_singleton) return 0;
+ state->LShift_type = make_type(state, "LShift", state->operator_type, NULL,
+ 0,
+ "LShift");
+ if (!state->LShift_type) return 0;
+ state->LShift_singleton = PyType_GenericNew((PyTypeObject
+ *)state->LShift_type, NULL,
+ NULL);
+ if (!state->LShift_singleton) return 0;
+ state->RShift_type = make_type(state, "RShift", state->operator_type, NULL,
+ 0,
+ "RShift");
+ if (!state->RShift_type) return 0;
+ state->RShift_singleton = PyType_GenericNew((PyTypeObject
+ *)state->RShift_type, NULL,
+ NULL);
+ if (!state->RShift_singleton) return 0;
+ state->BitOr_type = make_type(state, "BitOr", state->operator_type, NULL, 0,
+ "BitOr");
+ if (!state->BitOr_type) return 0;
+ state->BitOr_singleton = PyType_GenericNew((PyTypeObject
+ *)state->BitOr_type, NULL, NULL);
+ if (!state->BitOr_singleton) return 0;
+ state->BitXor_type = make_type(state, "BitXor", state->operator_type, NULL,
+ 0,
+ "BitXor");
+ if (!state->BitXor_type) return 0;
+ state->BitXor_singleton = PyType_GenericNew((PyTypeObject
+ *)state->BitXor_type, NULL,
+ NULL);
+ if (!state->BitXor_singleton) return 0;
+ state->BitAnd_type = make_type(state, "BitAnd", state->operator_type, NULL,
+ 0,
+ "BitAnd");
+ if (!state->BitAnd_type) return 0;
+ state->BitAnd_singleton = PyType_GenericNew((PyTypeObject
+ *)state->BitAnd_type, NULL,
+ NULL);
+ if (!state->BitAnd_singleton) return 0;
+ state->FloorDiv_type = make_type(state, "FloorDiv", state->operator_type,
+ NULL, 0,
+ "FloorDiv");
+ if (!state->FloorDiv_type) return 0;
+ state->FloorDiv_singleton = PyType_GenericNew((PyTypeObject
+ *)state->FloorDiv_type, NULL,
+ NULL);
+ if (!state->FloorDiv_singleton) return 0;
+ state->unaryop_type = make_type(state, "unaryop", state->AST_type, NULL, 0,
+ "unaryop = Invert | Not | UAdd | USub");
+ if (!state->unaryop_type) return 0;
+ if (!add_attributes(state, state->unaryop_type, NULL, 0)) return 0;
+ state->Invert_type = make_type(state, "Invert", state->unaryop_type, NULL,
+ 0,
+ "Invert");
+ if (!state->Invert_type) return 0;
+ state->Invert_singleton = PyType_GenericNew((PyTypeObject
+ *)state->Invert_type, NULL,
+ NULL);
+ if (!state->Invert_singleton) return 0;
+ state->Not_type = make_type(state, "Not", state->unaryop_type, NULL, 0,
+ "Not");
+ if (!state->Not_type) return 0;
+ state->Not_singleton = PyType_GenericNew((PyTypeObject *)state->Not_type,
+ NULL, NULL);
+ if (!state->Not_singleton) return 0;
+ state->UAdd_type = make_type(state, "UAdd", state->unaryop_type, NULL, 0,
+ "UAdd");
+ if (!state->UAdd_type) return 0;
+ state->UAdd_singleton = PyType_GenericNew((PyTypeObject *)state->UAdd_type,
+ NULL, NULL);
+ if (!state->UAdd_singleton) return 0;
+ state->USub_type = make_type(state, "USub", state->unaryop_type, NULL, 0,
+ "USub");
+ if (!state->USub_type) return 0;
+ state->USub_singleton = PyType_GenericNew((PyTypeObject *)state->USub_type,
+ NULL, NULL);
+ if (!state->USub_singleton) return 0;
+ state->cmpop_type = make_type(state, "cmpop", state->AST_type, NULL, 0,
+ "cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn");
+ if (!state->cmpop_type) return 0;
+ if (!add_attributes(state, state->cmpop_type, NULL, 0)) return 0;
+ state->Eq_type = make_type(state, "Eq", state->cmpop_type, NULL, 0,
+ "Eq");
+ if (!state->Eq_type) return 0;
+ state->Eq_singleton = PyType_GenericNew((PyTypeObject *)state->Eq_type,
+ NULL, NULL);
+ if (!state->Eq_singleton) return 0;
+ state->NotEq_type = make_type(state, "NotEq", state->cmpop_type, NULL, 0,
+ "NotEq");
+ if (!state->NotEq_type) return 0;
+ state->NotEq_singleton = PyType_GenericNew((PyTypeObject
+ *)state->NotEq_type, NULL, NULL);
+ if (!state->NotEq_singleton) return 0;
+ state->Lt_type = make_type(state, "Lt", state->cmpop_type, NULL, 0,
+ "Lt");
+ if (!state->Lt_type) return 0;
+ state->Lt_singleton = PyType_GenericNew((PyTypeObject *)state->Lt_type,
+ NULL, NULL);
+ if (!state->Lt_singleton) return 0;
+ state->LtE_type = make_type(state, "LtE", state->cmpop_type, NULL, 0,
+ "LtE");
+ if (!state->LtE_type) return 0;
+ state->LtE_singleton = PyType_GenericNew((PyTypeObject *)state->LtE_type,
+ NULL, NULL);
+ if (!state->LtE_singleton) return 0;
+ state->Gt_type = make_type(state, "Gt", state->cmpop_type, NULL, 0,
+ "Gt");
+ if (!state->Gt_type) return 0;
+ state->Gt_singleton = PyType_GenericNew((PyTypeObject *)state->Gt_type,
+ NULL, NULL);
+ if (!state->Gt_singleton) return 0;
+ state->GtE_type = make_type(state, "GtE", state->cmpop_type, NULL, 0,
+ "GtE");
+ if (!state->GtE_type) return 0;
+ state->GtE_singleton = PyType_GenericNew((PyTypeObject *)state->GtE_type,
+ NULL, NULL);
+ if (!state->GtE_singleton) return 0;
+ state->Is_type = make_type(state, "Is", state->cmpop_type, NULL, 0,
+ "Is");
+ if (!state->Is_type) return 0;
+ state->Is_singleton = PyType_GenericNew((PyTypeObject *)state->Is_type,
+ NULL, NULL);
+ if (!state->Is_singleton) return 0;
+ state->IsNot_type = make_type(state, "IsNot", state->cmpop_type, NULL, 0,
+ "IsNot");
+ if (!state->IsNot_type) return 0;
+ state->IsNot_singleton = PyType_GenericNew((PyTypeObject
+ *)state->IsNot_type, NULL, NULL);
+ if (!state->IsNot_singleton) return 0;
+ state->In_type = make_type(state, "In", state->cmpop_type, NULL, 0,
+ "In");
+ if (!state->In_type) return 0;
+ state->In_singleton = PyType_GenericNew((PyTypeObject *)state->In_type,
+ NULL, NULL);
+ if (!state->In_singleton) return 0;
+ state->NotIn_type = make_type(state, "NotIn", state->cmpop_type, NULL, 0,
+ "NotIn");
+ if (!state->NotIn_type) return 0;
+ state->NotIn_singleton = PyType_GenericNew((PyTypeObject
+ *)state->NotIn_type, NULL, NULL);
+ if (!state->NotIn_singleton) return 0;
+ state->comprehension_type = make_type(state, "comprehension",
+ state->AST_type,
+ comprehension_fields, 4,
+ "comprehension(expr target, expr iter, expr* ifs, int is_async)");
+ if (!state->comprehension_type) return 0;
+ if (!add_attributes(state, state->comprehension_type, NULL, 0)) return 0;
+ state->excepthandler_type = make_type(state, "excepthandler",
+ state->AST_type, NULL, 0,
+ "excepthandler = ExceptHandler(expr? type, identifier? name, stmt* body)");
+ if (!state->excepthandler_type) return 0;
+ if (!add_attributes(state, state->excepthandler_type,
+ excepthandler_attributes, 4)) return 0;
+ if (PyObject_SetAttr(state->excepthandler_type, state->end_lineno, Py_None)
+ == -1)
+ return 0;
+ if (PyObject_SetAttr(state->excepthandler_type, state->end_col_offset,
+ Py_None) == -1)
+ return 0;
+ state->ExceptHandler_type = make_type(state, "ExceptHandler",
+ state->excepthandler_type,
+ ExceptHandler_fields, 3,
+ "ExceptHandler(expr? type, identifier? name, stmt* body)");
+ if (!state->ExceptHandler_type) return 0;
+ if (PyObject_SetAttr(state->ExceptHandler_type, state->type, Py_None) == -1)
+ return 0;
+ if (PyObject_SetAttr(state->ExceptHandler_type, state->name, Py_None) == -1)
+ return 0;
+ state->arguments_type = make_type(state, "arguments", state->AST_type,
+ arguments_fields, 7,
+ "arguments(arg* posonlyargs, arg* args, arg? vararg, arg* kwonlyargs, expr* kw_defaults, arg? kwarg, expr* defaults)");
+ if (!state->arguments_type) return 0;
+ if (!add_attributes(state, state->arguments_type, NULL, 0)) return 0;
+ if (PyObject_SetAttr(state->arguments_type, state->vararg, Py_None) == -1)
+ return 0;
+ if (PyObject_SetAttr(state->arguments_type, state->kwarg, Py_None) == -1)
+ return 0;
+ state->arg_type = make_type(state, "arg", state->AST_type, arg_fields, 3,
+ "arg(identifier arg, expr? annotation, string? type_comment)");
+ if (!state->arg_type) return 0;
+ if (!add_attributes(state, state->arg_type, arg_attributes, 4)) return 0;
+ if (PyObject_SetAttr(state->arg_type, state->annotation, Py_None) == -1)
+ return 0;
+ if (PyObject_SetAttr(state->arg_type, state->type_comment, Py_None) == -1)
+ return 0;
+ if (PyObject_SetAttr(state->arg_type, state->end_lineno, Py_None) == -1)
+ return 0;
+ if (PyObject_SetAttr(state->arg_type, state->end_col_offset, Py_None) == -1)
+ return 0;
+ state->keyword_type = make_type(state, "keyword", state->AST_type,
+ keyword_fields, 2,
+ "keyword(identifier? arg, expr value)");
+ if (!state->keyword_type) return 0;
+ if (!add_attributes(state, state->keyword_type, keyword_attributes, 4))
+ return 0;
+ if (PyObject_SetAttr(state->keyword_type, state->arg, Py_None) == -1)
+ return 0;
+ if (PyObject_SetAttr(state->keyword_type, state->end_lineno, Py_None) == -1)
+ return 0;
+ if (PyObject_SetAttr(state->keyword_type, state->end_col_offset, Py_None)
+ == -1)
+ return 0;
+ state->alias_type = make_type(state, "alias", state->AST_type,
+ alias_fields, 2,
+ "alias(identifier name, identifier? asname)");
+ if (!state->alias_type) return 0;
+ if (!add_attributes(state, state->alias_type, NULL, 0)) return 0;
+ if (PyObject_SetAttr(state->alias_type, state->asname, Py_None) == -1)
+ return 0;
+ state->withitem_type = make_type(state, "withitem", state->AST_type,
+ withitem_fields, 2,
+ "withitem(expr context_expr, expr? optional_vars)");
+ if (!state->withitem_type) return 0;
+ if (!add_attributes(state, state->withitem_type, NULL, 0)) return 0;
+ if (PyObject_SetAttr(state->withitem_type, state->optional_vars, Py_None)
+ == -1)
+ return 0;
+ state->type_ignore_type = make_type(state, "type_ignore", state->AST_type,
+ NULL, 0,
+ "type_ignore = TypeIgnore(int lineno, string tag)");
+ if (!state->type_ignore_type) return 0;
+ if (!add_attributes(state, state->type_ignore_type, NULL, 0)) return 0;
+ state->TypeIgnore_type = make_type(state, "TypeIgnore",
+ state->type_ignore_type,
+ TypeIgnore_fields, 2,
+ "TypeIgnore(int lineno, string tag)");
+ if (!state->TypeIgnore_type) return 0;
+ state->initialized = 1;
+ return 1;
+}
+
+static int obj2ast_mod(astmodulestate *state, PyObject* obj, mod_ty* out,
+ PyArena* arena);
+static int obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out,
+ PyArena* arena);
+static int obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out,
+ PyArena* arena);
+static int obj2ast_expr_context(astmodulestate *state, PyObject* obj,
+ expr_context_ty* out, PyArena* arena);
+static int obj2ast_boolop(astmodulestate *state, PyObject* obj, boolop_ty* out,
+ PyArena* arena);
+static int obj2ast_operator(astmodulestate *state, PyObject* obj, operator_ty*
+ out, PyArena* arena);
+static int obj2ast_unaryop(astmodulestate *state, PyObject* obj, unaryop_ty*
+ out, PyArena* arena);
+static int obj2ast_cmpop(astmodulestate *state, PyObject* obj, cmpop_ty* out,
+ PyArena* arena);
+static int obj2ast_comprehension(astmodulestate *state, PyObject* obj,
+ comprehension_ty* out, PyArena* arena);
+static int obj2ast_excepthandler(astmodulestate *state, PyObject* obj,
+ excepthandler_ty* out, PyArena* arena);
+static int obj2ast_arguments(astmodulestate *state, PyObject* obj,
+ arguments_ty* out, PyArena* arena);
+static int obj2ast_arg(astmodulestate *state, PyObject* obj, arg_ty* out,
+ PyArena* arena);
+static int obj2ast_keyword(astmodulestate *state, PyObject* obj, keyword_ty*
+ out, PyArena* arena);
+static int obj2ast_alias(astmodulestate *state, PyObject* obj, alias_ty* out,
+ PyArena* arena);
+static int obj2ast_withitem(astmodulestate *state, PyObject* obj, withitem_ty*
+ out, PyArena* arena);
+static int obj2ast_type_ignore(astmodulestate *state, PyObject* obj,
+ type_ignore_ty* out, PyArena* arena);
+
+mod_ty
+Module(asdl_seq * body, asdl_seq * type_ignores, PyArena *arena)
+{
+ mod_ty p;
+ p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = Module_kind;
+ p->v.Module.body = body;
+ p->v.Module.type_ignores = type_ignores;
+ return p;
+}
+
+mod_ty
+Interactive(asdl_seq * body, PyArena *arena)
+{
+ mod_ty p;
+ p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = Interactive_kind;
+ p->v.Interactive.body = body;
+ return p;
+}
+
+mod_ty
+Expression(expr_ty body, PyArena *arena)
+{
+ mod_ty p;
+ if (!body) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'body' is required for Expression");
+ return NULL;
+ }
+ p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = Expression_kind;
+ p->v.Expression.body = body;
+ return p;
+}
+
+mod_ty
+FunctionType(asdl_seq * argtypes, expr_ty returns, PyArena *arena)
+{
+ mod_ty p;
+ if (!returns) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'returns' is required for FunctionType");
+ return NULL;
+ }
+ p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = FunctionType_kind;
+ p->v.FunctionType.argtypes = argtypes;
+ p->v.FunctionType.returns = returns;
+ return p;
+}
+
+stmt_ty
+FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq *
+ decorator_list, expr_ty returns, string type_comment, int lineno,
+ int col_offset, int end_lineno, int end_col_offset, PyArena *arena)
+{
+ stmt_ty p;
+ if (!name) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'name' is required for FunctionDef");
+ return NULL;
+ }
+ if (!args) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'args' is required for FunctionDef");
+ return NULL;
+ }
+ p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = FunctionDef_kind;
+ p->v.FunctionDef.name = name;
+ p->v.FunctionDef.args = args;
+ p->v.FunctionDef.body = body;
+ p->v.FunctionDef.decorator_list = decorator_list;
+ p->v.FunctionDef.returns = returns;
+ p->v.FunctionDef.type_comment = type_comment;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+AsyncFunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq
+ * decorator_list, expr_ty returns, string type_comment, int
+ lineno, int col_offset, int end_lineno, int end_col_offset,
+ PyArena *arena)
+{
+ stmt_ty p;
+ if (!name) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'name' is required for AsyncFunctionDef");
+ return NULL;
+ }
+ if (!args) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'args' is required for AsyncFunctionDef");
+ return NULL;
+ }
+ p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = AsyncFunctionDef_kind;
+ p->v.AsyncFunctionDef.name = name;
+ p->v.AsyncFunctionDef.args = args;
+ p->v.AsyncFunctionDef.body = body;
+ p->v.AsyncFunctionDef.decorator_list = decorator_list;
+ p->v.AsyncFunctionDef.returns = returns;
+ p->v.AsyncFunctionDef.type_comment = type_comment;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords, asdl_seq *
+ body, asdl_seq * decorator_list, int lineno, int col_offset, int
+ end_lineno, int end_col_offset, PyArena *arena)
+{
+ stmt_ty p;
+ if (!name) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'name' is required for ClassDef");
+ return NULL;
+ }
+ p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = ClassDef_kind;
+ p->v.ClassDef.name = name;
+ p->v.ClassDef.bases = bases;
+ p->v.ClassDef.keywords = keywords;
+ p->v.ClassDef.body = body;
+ p->v.ClassDef.decorator_list = decorator_list;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+Return(expr_ty value, 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));
+ if (!p)
+ return NULL;
+ p->kind = Return_kind;
+ p->v.Return.value = value;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+Delete(asdl_seq * targets, 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));
+ if (!p)
+ return NULL;
+ p->kind = Delete_kind;
+ p->v.Delete.targets = targets;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+Assign(asdl_seq * targets, expr_ty value, string type_comment, int lineno, int
+ col_offset, int end_lineno, int end_col_offset, PyArena *arena)
+{
+ stmt_ty p;
+ if (!value) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'value' is required for Assign");
+ return NULL;
+ }
+ p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = Assign_kind;
+ p->v.Assign.targets = targets;
+ p->v.Assign.value = value;
+ p->v.Assign.type_comment = type_comment;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno, int
+ col_offset, int end_lineno, int end_col_offset, PyArena *arena)
+{
+ stmt_ty p;
+ if (!target) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'target' is required for AugAssign");
+ return NULL;
+ }
+ if (!op) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'op' is required for AugAssign");
+ return NULL;
+ }
+ if (!value) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'value' is required for AugAssign");
+ return NULL;
+ }
+ p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = AugAssign_kind;
+ p->v.AugAssign.target = target;
+ p->v.AugAssign.op = op;
+ p->v.AugAssign.value = value;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int simple, int
+ lineno, int col_offset, int end_lineno, int end_col_offset, PyArena
+ *arena)
+{
+ stmt_ty p;
+ if (!target) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'target' is required for AnnAssign");
+ return NULL;
+ }
+ if (!annotation) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'annotation' is required for AnnAssign");
+ return NULL;
+ }
+ p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = AnnAssign_kind;
+ p->v.AnnAssign.target = target;
+ p->v.AnnAssign.annotation = annotation;
+ p->v.AnnAssign.value = value;
+ p->v.AnnAssign.simple = simple;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, string
+ type_comment, int lineno, int col_offset, int end_lineno, int
+ end_col_offset, PyArena *arena)
+{
+ stmt_ty p;
+ if (!target) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'target' is required for For");
+ return NULL;
+ }
+ if (!iter) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'iter' is required for For");
+ return NULL;
+ }
+ p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = For_kind;
+ p->v.For.target = target;
+ p->v.For.iter = iter;
+ p->v.For.body = body;
+ p->v.For.orelse = orelse;
+ p->v.For.type_comment = type_comment;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+AsyncFor(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse,
+ string type_comment, int lineno, int col_offset, int end_lineno, int
+ end_col_offset, PyArena *arena)
+{
+ stmt_ty p;
+ if (!target) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'target' is required for AsyncFor");
+ return NULL;
+ }
+ if (!iter) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'iter' is required for AsyncFor");
+ return NULL;
+ }
+ p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = AsyncFor_kind;
+ p->v.AsyncFor.target = target;
+ p->v.AsyncFor.iter = iter;
+ p->v.AsyncFor.body = body;
+ p->v.AsyncFor.orelse = orelse;
+ p->v.AsyncFor.type_comment = type_comment;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int
+ col_offset, int end_lineno, int end_col_offset, PyArena *arena)
+{
+ stmt_ty p;
+ if (!test) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'test' is required for While");
+ return NULL;
+ }
+ p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = While_kind;
+ p->v.While.test = test;
+ p->v.While.body = body;
+ p->v.While.orelse = orelse;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int
+ col_offset, int end_lineno, int end_col_offset, PyArena *arena)
+{
+ stmt_ty p;
+ if (!test) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'test' is required for If");
+ return NULL;
+ }
+ p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = If_kind;
+ p->v.If.test = test;
+ p->v.If.body = body;
+ p->v.If.orelse = orelse;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+With(asdl_seq * items, asdl_seq * body, string type_comment, 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));
+ if (!p)
+ return NULL;
+ p->kind = With_kind;
+ p->v.With.items = items;
+ p->v.With.body = body;
+ p->v.With.type_comment = type_comment;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+AsyncWith(asdl_seq * items, asdl_seq * body, string type_comment, 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));
+ if (!p)
+ return NULL;
+ p->kind = AsyncWith_kind;
+ p->v.AsyncWith.items = items;
+ p->v.AsyncWith.body = body;
+ p->v.AsyncWith.type_comment = type_comment;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+Raise(expr_ty exc, expr_ty cause, 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));
+ if (!p)
+ return NULL;
+ p->kind = Raise_kind;
+ p->v.Raise.exc = exc;
+ p->v.Raise.cause = cause;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+Try(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, asdl_seq *
+ finalbody, 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));
+ if (!p)
+ return NULL;
+ p->kind = Try_kind;
+ p->v.Try.body = body;
+ p->v.Try.handlers = handlers;
+ p->v.Try.orelse = orelse;
+ p->v.Try.finalbody = finalbody;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, int end_lineno,
+ int end_col_offset, PyArena *arena)
+{
+ stmt_ty p;
+ if (!test) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'test' is required for Assert");
+ return NULL;
+ }
+ p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = Assert_kind;
+ p->v.Assert.test = test;
+ p->v.Assert.msg = msg;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+Import(asdl_seq * names, 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));
+ if (!p)
+ return NULL;
+ p->kind = Import_kind;
+ p->v.Import.names = names;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+ImportFrom(identifier module, asdl_seq * names, int level, 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));
+ if (!p)
+ return NULL;
+ p->kind = ImportFrom_kind;
+ p->v.ImportFrom.module = module;
+ p->v.ImportFrom.names = names;
+ p->v.ImportFrom.level = level;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+Global(asdl_seq * names, 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));
+ if (!p)
+ return NULL;
+ p->kind = Global_kind;
+ p->v.Global.names = names;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+Nonlocal(asdl_seq * names, 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));
+ if (!p)
+ return NULL;
+ p->kind = Nonlocal_kind;
+ p->v.Nonlocal.names = names;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+Expr(expr_ty value, int lineno, int col_offset, int end_lineno, int
+ end_col_offset, PyArena *arena)
+{
+ stmt_ty p;
+ if (!value) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'value' is required for Expr");
+ return NULL;
+ }
+ p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = Expr_kind;
+ p->v.Expr.value = value;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+Pass(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));
+ if (!p)
+ return NULL;
+ p->kind = Pass_kind;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+Break(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));
+ if (!p)
+ return NULL;
+ p->kind = Break_kind;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+stmt_ty
+Continue(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));
+ if (!p)
+ return NULL;
+ p->kind = Continue_kind;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+BoolOp(boolop_ty op, asdl_seq * values, int lineno, int col_offset, int
+ end_lineno, int end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ if (!op) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'op' is required for BoolOp");
+ return NULL;
+ }
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = BoolOp_kind;
+ p->v.BoolOp.op = op;
+ p->v.BoolOp.values = values;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+NamedExpr(expr_ty target, expr_ty value, int lineno, int col_offset, int
+ end_lineno, int end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ if (!target) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'target' is required for NamedExpr");
+ return NULL;
+ }
+ if (!value) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'value' is required for NamedExpr");
+ return NULL;
+ }
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = NamedExpr_kind;
+ p->v.NamedExpr.target = target;
+ p->v.NamedExpr.value = value;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int col_offset,
+ int end_lineno, int end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ if (!left) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'left' is required for BinOp");
+ return NULL;
+ }
+ if (!op) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'op' is required for BinOp");
+ return NULL;
+ }
+ if (!right) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'right' is required for BinOp");
+ return NULL;
+ }
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = BinOp_kind;
+ p->v.BinOp.left = left;
+ p->v.BinOp.op = op;
+ p->v.BinOp.right = right;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset, int
+ end_lineno, int end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ if (!op) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'op' is required for UnaryOp");
+ return NULL;
+ }
+ if (!operand) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'operand' is required for UnaryOp");
+ return NULL;
+ }
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = UnaryOp_kind;
+ p->v.UnaryOp.op = op;
+ p->v.UnaryOp.operand = operand;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset, int
+ end_lineno, int end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ if (!args) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'args' is required for Lambda");
+ return NULL;
+ }
+ if (!body) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'body' is required for Lambda");
+ return NULL;
+ }
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = Lambda_kind;
+ p->v.Lambda.args = args;
+ p->v.Lambda.body = body;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int col_offset,
+ int end_lineno, int end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ if (!test) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'test' is required for IfExp");
+ return NULL;
+ }
+ if (!body) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'body' is required for IfExp");
+ return NULL;
+ }
+ if (!orelse) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'orelse' is required for IfExp");
+ return NULL;
+ }
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = IfExp_kind;
+ p->v.IfExp.test = test;
+ p->v.IfExp.body = body;
+ p->v.IfExp.orelse = orelse;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+Dict(asdl_seq * keys, asdl_seq * values, int lineno, int col_offset, int
+ end_lineno, int end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = Dict_kind;
+ p->v.Dict.keys = keys;
+ p->v.Dict.values = values;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+Set(asdl_seq * elts, int lineno, int col_offset, int end_lineno, int
+ end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = Set_kind;
+ p->v.Set.elts = elts;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+ListComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, int
+ end_lineno, int end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ if (!elt) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'elt' is required for ListComp");
+ return NULL;
+ }
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = ListComp_kind;
+ p->v.ListComp.elt = elt;
+ p->v.ListComp.generators = generators;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+SetComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, int
+ end_lineno, int end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ if (!elt) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'elt' is required for SetComp");
+ return NULL;
+ }
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = SetComp_kind;
+ p->v.SetComp.elt = elt;
+ p->v.SetComp.generators = generators;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+DictComp(expr_ty key, expr_ty value, asdl_seq * generators, int lineno, int
+ col_offset, int end_lineno, int end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ if (!key) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'key' is required for DictComp");
+ return NULL;
+ }
+ if (!value) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'value' is required for DictComp");
+ return NULL;
+ }
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = DictComp_kind;
+ p->v.DictComp.key = key;
+ p->v.DictComp.value = value;
+ p->v.DictComp.generators = generators;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset,
+ int end_lineno, int end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ if (!elt) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'elt' is required for GeneratorExp");
+ return NULL;
+ }
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = GeneratorExp_kind;
+ p->v.GeneratorExp.elt = elt;
+ p->v.GeneratorExp.generators = generators;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+Await(expr_ty value, int lineno, int col_offset, int end_lineno, int
+ end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ if (!value) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'value' is required for Await");
+ return NULL;
+ }
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = Await_kind;
+ p->v.Await.value = value;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+Yield(expr_ty value, int lineno, int col_offset, int end_lineno, int
+ end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = Yield_kind;
+ p->v.Yield.value = value;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+YieldFrom(expr_ty value, int lineno, int col_offset, int end_lineno, int
+ end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ if (!value) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'value' is required for YieldFrom");
+ return NULL;
+ }
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = YieldFrom_kind;
+ p->v.YieldFrom.value = value;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, int lineno,
+ int col_offset, int end_lineno, int end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ if (!left) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'left' is required for Compare");
+ return NULL;
+ }
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = Compare_kind;
+ p->v.Compare.left = left;
+ p->v.Compare.ops = ops;
+ p->v.Compare.comparators = comparators;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, int lineno, int
+ col_offset, int end_lineno, int end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ if (!func) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'func' is required for Call");
+ return NULL;
+ }
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = Call_kind;
+ p->v.Call.func = func;
+ p->v.Call.args = args;
+ p->v.Call.keywords = keywords;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+FormattedValue(expr_ty value, int conversion, expr_ty format_spec, int lineno,
+ int col_offset, int end_lineno, int end_col_offset, PyArena
+ *arena)
+{
+ expr_ty p;
+ if (!value) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'value' is required for FormattedValue");
+ return NULL;
+ }
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = FormattedValue_kind;
+ p->v.FormattedValue.value = value;
+ p->v.FormattedValue.conversion = conversion;
+ p->v.FormattedValue.format_spec = format_spec;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+JoinedStr(asdl_seq * values, int lineno, int col_offset, int end_lineno, int
+ end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = JoinedStr_kind;
+ p->v.JoinedStr.values = values;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+Constant(constant value, string kind, int lineno, int col_offset, int
+ end_lineno, int end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ if (!value) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'value' is required for Constant");
+ return NULL;
+ }
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = Constant_kind;
+ p->v.Constant.value = value;
+ p->v.Constant.kind = kind;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int lineno, int
+ col_offset, int end_lineno, int end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ if (!value) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'value' is required for Attribute");
+ return NULL;
+ }
+ if (!attr) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'attr' is required for Attribute");
+ return NULL;
+ }
+ if (!ctx) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'ctx' is required for Attribute");
+ return NULL;
+ }
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = Attribute_kind;
+ p->v.Attribute.value = value;
+ p->v.Attribute.attr = attr;
+ p->v.Attribute.ctx = ctx;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+Subscript(expr_ty value, expr_ty slice, expr_context_ty ctx, int lineno, int
+ col_offset, int end_lineno, int end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ if (!value) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'value' is required for Subscript");
+ return NULL;
+ }
+ if (!slice) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'slice' is required for Subscript");
+ return NULL;
+ }
+ if (!ctx) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'ctx' is required for Subscript");
+ return NULL;
+ }
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = Subscript_kind;
+ p->v.Subscript.value = value;
+ p->v.Subscript.slice = slice;
+ p->v.Subscript.ctx = ctx;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+Starred(expr_ty value, expr_context_ty ctx, int lineno, int col_offset, int
+ end_lineno, int end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ if (!value) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'value' is required for Starred");
+ return NULL;
+ }
+ if (!ctx) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'ctx' is required for Starred");
+ return NULL;
+ }
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = Starred_kind;
+ p->v.Starred.value = value;
+ p->v.Starred.ctx = ctx;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+Name(identifier id, expr_context_ty ctx, int lineno, int col_offset, int
+ end_lineno, int end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ if (!id) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'id' is required for Name");
+ return NULL;
+ }
+ if (!ctx) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'ctx' is required for Name");
+ return NULL;
+ }
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = Name_kind;
+ p->v.Name.id = id;
+ p->v.Name.ctx = ctx;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+List(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, int
+ end_lineno, int end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ if (!ctx) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'ctx' is required for List");
+ return NULL;
+ }
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = List_kind;
+ p->v.List.elts = elts;
+ p->v.List.ctx = ctx;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, int
+ end_lineno, int end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ if (!ctx) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'ctx' is required for Tuple");
+ return NULL;
+ }
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = Tuple_kind;
+ p->v.Tuple.elts = elts;
+ p->v.Tuple.ctx = ctx;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+expr_ty
+Slice(expr_ty lower, expr_ty upper, expr_ty step, int lineno, int col_offset,
+ int end_lineno, int end_col_offset, PyArena *arena)
+{
+ expr_ty p;
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = Slice_kind;
+ p->v.Slice.lower = lower;
+ p->v.Slice.upper = upper;
+ p->v.Slice.step = step;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+comprehension_ty
+comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs, int is_async,
+ PyArena *arena)
+{
+ comprehension_ty p;
+ if (!target) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'target' is required for comprehension");
+ return NULL;
+ }
+ if (!iter) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'iter' is required for comprehension");
+ return NULL;
+ }
+ p = (comprehension_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->target = target;
+ p->iter = iter;
+ p->ifs = ifs;
+ p->is_async = is_async;
+ return p;
+}
+
+excepthandler_ty
+ExceptHandler(expr_ty type, identifier name, asdl_seq * body, int lineno, int
+ col_offset, int end_lineno, int end_col_offset, PyArena *arena)
+{
+ excepthandler_ty p;
+ p = (excepthandler_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = ExceptHandler_kind;
+ p->v.ExceptHandler.type = type;
+ p->v.ExceptHandler.name = name;
+ p->v.ExceptHandler.body = body;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+arguments_ty
+arguments(asdl_seq * posonlyargs, asdl_seq * args, arg_ty vararg, asdl_seq *
+ kwonlyargs, asdl_seq * kw_defaults, arg_ty kwarg, asdl_seq *
+ defaults, PyArena *arena)
+{
+ arguments_ty p;
+ p = (arguments_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->posonlyargs = posonlyargs;
+ p->args = args;
+ p->vararg = vararg;
+ p->kwonlyargs = kwonlyargs;
+ p->kw_defaults = kw_defaults;
+ p->kwarg = kwarg;
+ p->defaults = defaults;
+ return p;
+}
+
+arg_ty
+arg(identifier arg, expr_ty annotation, string type_comment, int lineno, int
+ col_offset, int end_lineno, int end_col_offset, PyArena *arena)
+{
+ arg_ty p;
+ if (!arg) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'arg' is required for arg");
+ return NULL;
+ }
+ p = (arg_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->arg = arg;
+ p->annotation = annotation;
+ p->type_comment = type_comment;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+keyword_ty
+keyword(identifier arg, expr_ty value, int lineno, int col_offset, int
+ end_lineno, int end_col_offset, PyArena *arena)
+{
+ keyword_ty p;
+ if (!value) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'value' is required for keyword");
+ return NULL;
+ }
+ p = (keyword_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->arg = arg;
+ p->value = value;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ p->end_lineno = end_lineno;
+ p->end_col_offset = end_col_offset;
+ return p;
+}
+
+alias_ty
+alias(identifier name, identifier asname, PyArena *arena)
+{
+ alias_ty p;
+ if (!name) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'name' is required for alias");
+ return NULL;
+ }
+ p = (alias_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->name = name;
+ p->asname = asname;
+ return p;
+}
+
+withitem_ty
+withitem(expr_ty context_expr, expr_ty optional_vars, PyArena *arena)
+{
+ withitem_ty p;
+ if (!context_expr) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'context_expr' is required for withitem");
+ return NULL;
+ }
+ p = (withitem_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->context_expr = context_expr;
+ p->optional_vars = optional_vars;
+ return p;
+}
+
+type_ignore_ty
+TypeIgnore(int lineno, string tag, PyArena *arena)
+{
+ type_ignore_ty p;
+ if (!tag) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'tag' is required for TypeIgnore");
+ return NULL;
+ }
+ p = (type_ignore_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = TypeIgnore_kind;
+ p->v.TypeIgnore.lineno = lineno;
+ p->v.TypeIgnore.tag = tag;
+ return p;
+}
+
+
+PyObject*
+ast2obj_mod(astmodulestate *state, void* _o)
+{
+ mod_ty o = (mod_ty)_o;
+ PyObject *result = NULL, *value = NULL;
+ PyTypeObject *tp;
+ if (!o) {
+ Py_RETURN_NONE;
+ }
+ switch (o->kind) {
+ case Module_kind:
+ tp = (PyTypeObject *)state->Module_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_list(state, o->v.Module.body, ast2obj_stmt);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->body, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.Module.type_ignores,
+ ast2obj_type_ignore);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->type_ignores, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Interactive_kind:
+ tp = (PyTypeObject *)state->Interactive_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_list(state, o->v.Interactive.body, ast2obj_stmt);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->body, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Expression_kind:
+ tp = (PyTypeObject *)state->Expression_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.Expression.body);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->body, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case FunctionType_kind:
+ tp = (PyTypeObject *)state->FunctionType_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_list(state, o->v.FunctionType.argtypes, ast2obj_expr);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->argtypes, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->v.FunctionType.returns);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->returns, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ }
+ return result;
+failed:
+ Py_XDECREF(value);
+ Py_XDECREF(result);
+ return NULL;
+}
+
+PyObject*
+ast2obj_stmt(astmodulestate *state, void* _o)
+{
+ stmt_ty o = (stmt_ty)_o;
+ PyObject *result = NULL, *value = NULL;
+ PyTypeObject *tp;
+ if (!o) {
+ Py_RETURN_NONE;
+ }
+ switch (o->kind) {
+ case FunctionDef_kind:
+ tp = (PyTypeObject *)state->FunctionDef_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_identifier(state, o->v.FunctionDef.name);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->name, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_arguments(state, o->v.FunctionDef.args);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->args, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.FunctionDef.body, ast2obj_stmt);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->body, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.FunctionDef.decorator_list,
+ ast2obj_expr);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->decorator_list, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->v.FunctionDef.returns);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->returns, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_string(state, o->v.FunctionDef.type_comment);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->type_comment, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case AsyncFunctionDef_kind:
+ tp = (PyTypeObject *)state->AsyncFunctionDef_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_identifier(state, o->v.AsyncFunctionDef.name);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->name, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_arguments(state, o->v.AsyncFunctionDef.args);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->args, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.AsyncFunctionDef.body, ast2obj_stmt);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->body, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.AsyncFunctionDef.decorator_list,
+ ast2obj_expr);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->decorator_list, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->v.AsyncFunctionDef.returns);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->returns, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_string(state, o->v.AsyncFunctionDef.type_comment);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->type_comment, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case ClassDef_kind:
+ tp = (PyTypeObject *)state->ClassDef_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_identifier(state, o->v.ClassDef.name);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->name, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.ClassDef.bases, ast2obj_expr);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->bases, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.ClassDef.keywords, ast2obj_keyword);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->keywords, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.ClassDef.body, ast2obj_stmt);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->body, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.ClassDef.decorator_list, ast2obj_expr);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->decorator_list, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Return_kind:
+ tp = (PyTypeObject *)state->Return_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.Return.value);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->value, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Delete_kind:
+ tp = (PyTypeObject *)state->Delete_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_list(state, o->v.Delete.targets, ast2obj_expr);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->targets, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Assign_kind:
+ tp = (PyTypeObject *)state->Assign_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_list(state, o->v.Assign.targets, ast2obj_expr);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->targets, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->v.Assign.value);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->value, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_string(state, o->v.Assign.type_comment);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->type_comment, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case AugAssign_kind:
+ tp = (PyTypeObject *)state->AugAssign_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.AugAssign.target);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->target, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_operator(state, o->v.AugAssign.op);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->op, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->v.AugAssign.value);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->value, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case AnnAssign_kind:
+ tp = (PyTypeObject *)state->AnnAssign_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.AnnAssign.target);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->target, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->v.AnnAssign.annotation);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->annotation, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->v.AnnAssign.value);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->value, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_int(state, o->v.AnnAssign.simple);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->simple, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case For_kind:
+ tp = (PyTypeObject *)state->For_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.For.target);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->target, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->v.For.iter);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->iter, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.For.body, ast2obj_stmt);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->body, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.For.orelse, ast2obj_stmt);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->orelse, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_string(state, o->v.For.type_comment);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->type_comment, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case AsyncFor_kind:
+ tp = (PyTypeObject *)state->AsyncFor_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.AsyncFor.target);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->target, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->v.AsyncFor.iter);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->iter, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.AsyncFor.body, ast2obj_stmt);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->body, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.AsyncFor.orelse, ast2obj_stmt);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->orelse, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_string(state, o->v.AsyncFor.type_comment);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->type_comment, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case While_kind:
+ tp = (PyTypeObject *)state->While_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.While.test);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->test, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.While.body, ast2obj_stmt);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->body, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.While.orelse, ast2obj_stmt);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->orelse, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case If_kind:
+ tp = (PyTypeObject *)state->If_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.If.test);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->test, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.If.body, ast2obj_stmt);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->body, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.If.orelse, ast2obj_stmt);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->orelse, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case With_kind:
+ tp = (PyTypeObject *)state->With_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_list(state, o->v.With.items, ast2obj_withitem);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->items, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.With.body, ast2obj_stmt);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->body, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_string(state, o->v.With.type_comment);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->type_comment, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case AsyncWith_kind:
+ tp = (PyTypeObject *)state->AsyncWith_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_list(state, o->v.AsyncWith.items, ast2obj_withitem);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->items, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.AsyncWith.body, ast2obj_stmt);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->body, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_string(state, o->v.AsyncWith.type_comment);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->type_comment, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Raise_kind:
+ tp = (PyTypeObject *)state->Raise_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.Raise.exc);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->exc, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->v.Raise.cause);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->cause, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Try_kind:
+ tp = (PyTypeObject *)state->Try_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_list(state, o->v.Try.body, ast2obj_stmt);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->body, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.Try.handlers, ast2obj_excepthandler);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->handlers, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.Try.orelse, ast2obj_stmt);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->orelse, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.Try.finalbody, ast2obj_stmt);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->finalbody, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Assert_kind:
+ tp = (PyTypeObject *)state->Assert_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.Assert.test);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->test, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->v.Assert.msg);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->msg, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Import_kind:
+ tp = (PyTypeObject *)state->Import_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_list(state, o->v.Import.names, ast2obj_alias);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->names, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case ImportFrom_kind:
+ tp = (PyTypeObject *)state->ImportFrom_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_identifier(state, o->v.ImportFrom.module);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->module, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.ImportFrom.names, ast2obj_alias);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->names, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_int(state, o->v.ImportFrom.level);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->level, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Global_kind:
+ tp = (PyTypeObject *)state->Global_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_list(state, o->v.Global.names, ast2obj_identifier);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->names, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Nonlocal_kind:
+ tp = (PyTypeObject *)state->Nonlocal_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_list(state, o->v.Nonlocal.names, ast2obj_identifier);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->names, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Expr_kind:
+ tp = (PyTypeObject *)state->Expr_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.Expr.value);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->value, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Pass_kind:
+ tp = (PyTypeObject *)state->Pass_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ break;
+ case Break_kind:
+ tp = (PyTypeObject *)state->Break_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ break;
+ case Continue_kind:
+ tp = (PyTypeObject *)state->Continue_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ break;
+ }
+ value = ast2obj_int(state, o->lineno);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->lineno, value) < 0)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_int(state, o->col_offset);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->col_offset, value) < 0)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_int(state, o->end_lineno);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->end_lineno, value) < 0)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_int(state, o->end_col_offset);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->end_col_offset, value) < 0)
+ goto failed;
+ Py_DECREF(value);
+ return result;
+failed:
+ Py_XDECREF(value);
+ Py_XDECREF(result);
+ return NULL;
+}
+
+PyObject*
+ast2obj_expr(astmodulestate *state, void* _o)
+{
+ expr_ty o = (expr_ty)_o;
+ PyObject *result = NULL, *value = NULL;
+ PyTypeObject *tp;
+ if (!o) {
+ Py_RETURN_NONE;
+ }
+ switch (o->kind) {
+ case BoolOp_kind:
+ tp = (PyTypeObject *)state->BoolOp_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_boolop(state, o->v.BoolOp.op);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->op, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.BoolOp.values, ast2obj_expr);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->values, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case NamedExpr_kind:
+ tp = (PyTypeObject *)state->NamedExpr_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.NamedExpr.target);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->target, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->v.NamedExpr.value);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->value, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case BinOp_kind:
+ tp = (PyTypeObject *)state->BinOp_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.BinOp.left);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->left, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_operator(state, o->v.BinOp.op);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->op, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->v.BinOp.right);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->right, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case UnaryOp_kind:
+ tp = (PyTypeObject *)state->UnaryOp_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_unaryop(state, o->v.UnaryOp.op);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->op, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->v.UnaryOp.operand);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->operand, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Lambda_kind:
+ tp = (PyTypeObject *)state->Lambda_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_arguments(state, o->v.Lambda.args);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->args, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->v.Lambda.body);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->body, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case IfExp_kind:
+ tp = (PyTypeObject *)state->IfExp_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.IfExp.test);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->test, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->v.IfExp.body);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->body, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->v.IfExp.orelse);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->orelse, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Dict_kind:
+ tp = (PyTypeObject *)state->Dict_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_list(state, o->v.Dict.keys, ast2obj_expr);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->keys, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.Dict.values, ast2obj_expr);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->values, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Set_kind:
+ tp = (PyTypeObject *)state->Set_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_list(state, o->v.Set.elts, ast2obj_expr);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->elts, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case ListComp_kind:
+ tp = (PyTypeObject *)state->ListComp_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.ListComp.elt);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->elt, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.ListComp.generators,
+ ast2obj_comprehension);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->generators, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case SetComp_kind:
+ tp = (PyTypeObject *)state->SetComp_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.SetComp.elt);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->elt, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.SetComp.generators,
+ ast2obj_comprehension);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->generators, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case DictComp_kind:
+ tp = (PyTypeObject *)state->DictComp_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.DictComp.key);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->key, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->v.DictComp.value);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->value, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.DictComp.generators,
+ ast2obj_comprehension);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->generators, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case GeneratorExp_kind:
+ tp = (PyTypeObject *)state->GeneratorExp_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.GeneratorExp.elt);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->elt, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.GeneratorExp.generators,
+ ast2obj_comprehension);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->generators, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Await_kind:
+ tp = (PyTypeObject *)state->Await_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.Await.value);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->value, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Yield_kind:
+ tp = (PyTypeObject *)state->Yield_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.Yield.value);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->value, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case YieldFrom_kind:
+ tp = (PyTypeObject *)state->YieldFrom_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.YieldFrom.value);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->value, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Compare_kind:
+ tp = (PyTypeObject *)state->Compare_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.Compare.left);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->left, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ {
+ Py_ssize_t i, n = asdl_seq_LEN(o->v.Compare.ops);
+ value = PyList_New(n);
+ if (!value) goto failed;
+ for(i = 0; i < n; i++)
+ PyList_SET_ITEM(value, i, ast2obj_cmpop(state, (cmpop_ty)asdl_seq_GET(o->v.Compare.ops, i)));
+ }
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->ops, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.Compare.comparators, ast2obj_expr);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->comparators, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Call_kind:
+ tp = (PyTypeObject *)state->Call_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.Call.func);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->func, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.Call.args, ast2obj_expr);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->args, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.Call.keywords, ast2obj_keyword);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->keywords, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case FormattedValue_kind:
+ tp = (PyTypeObject *)state->FormattedValue_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.FormattedValue.value);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->value, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_int(state, o->v.FormattedValue.conversion);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->conversion, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->v.FormattedValue.format_spec);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->format_spec, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case JoinedStr_kind:
+ tp = (PyTypeObject *)state->JoinedStr_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_list(state, o->v.JoinedStr.values, ast2obj_expr);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->values, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Constant_kind:
+ tp = (PyTypeObject *)state->Constant_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_constant(state, o->v.Constant.value);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->value, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_string(state, o->v.Constant.kind);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->kind, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Attribute_kind:
+ tp = (PyTypeObject *)state->Attribute_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.Attribute.value);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->value, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_identifier(state, o->v.Attribute.attr);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->attr, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr_context(state, o->v.Attribute.ctx);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->ctx, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Subscript_kind:
+ tp = (PyTypeObject *)state->Subscript_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.Subscript.value);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->value, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->v.Subscript.slice);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->slice, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr_context(state, o->v.Subscript.ctx);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->ctx, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Starred_kind:
+ tp = (PyTypeObject *)state->Starred_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.Starred.value);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->value, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr_context(state, o->v.Starred.ctx);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->ctx, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Name_kind:
+ tp = (PyTypeObject *)state->Name_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_identifier(state, o->v.Name.id);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->id, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr_context(state, o->v.Name.ctx);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->ctx, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case List_kind:
+ tp = (PyTypeObject *)state->List_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_list(state, o->v.List.elts, ast2obj_expr);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->elts, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr_context(state, o->v.List.ctx);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->ctx, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Tuple_kind:
+ tp = (PyTypeObject *)state->Tuple_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_list(state, o->v.Tuple.elts, ast2obj_expr);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->elts, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr_context(state, o->v.Tuple.ctx);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->ctx, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ case Slice_kind:
+ tp = (PyTypeObject *)state->Slice_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.Slice.lower);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->lower, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->v.Slice.upper);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->upper, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->v.Slice.step);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->step, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ }
+ value = ast2obj_int(state, o->lineno);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->lineno, value) < 0)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_int(state, o->col_offset);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->col_offset, value) < 0)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_int(state, o->end_lineno);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->end_lineno, value) < 0)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_int(state, o->end_col_offset);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->end_col_offset, value) < 0)
+ goto failed;
+ Py_DECREF(value);
+ return result;
+failed:
+ Py_XDECREF(value);
+ Py_XDECREF(result);
+ return NULL;
+}
+
+PyObject* ast2obj_expr_context(astmodulestate *state, expr_context_ty o)
+{
+ switch(o) {
+ case Load:
+ Py_INCREF(state->Load_singleton);
+ return state->Load_singleton;
+ case Store:
+ Py_INCREF(state->Store_singleton);
+ return state->Store_singleton;
+ case Del:
+ Py_INCREF(state->Del_singleton);
+ return state->Del_singleton;
+ }
+ Py_UNREACHABLE();
+}
+PyObject* ast2obj_boolop(astmodulestate *state, boolop_ty o)
+{
+ switch(o) {
+ case And:
+ Py_INCREF(state->And_singleton);
+ return state->And_singleton;
+ case Or:
+ Py_INCREF(state->Or_singleton);
+ return state->Or_singleton;
+ }
+ Py_UNREACHABLE();
+}
+PyObject* ast2obj_operator(astmodulestate *state, operator_ty o)
+{
+ switch(o) {
+ case Add:
+ Py_INCREF(state->Add_singleton);
+ return state->Add_singleton;
+ case Sub:
+ Py_INCREF(state->Sub_singleton);
+ return state->Sub_singleton;
+ case Mult:
+ Py_INCREF(state->Mult_singleton);
+ return state->Mult_singleton;
+ case MatMult:
+ Py_INCREF(state->MatMult_singleton);
+ return state->MatMult_singleton;
+ case Div:
+ Py_INCREF(state->Div_singleton);
+ return state->Div_singleton;
+ case Mod:
+ Py_INCREF(state->Mod_singleton);
+ return state->Mod_singleton;
+ case Pow:
+ Py_INCREF(state->Pow_singleton);
+ return state->Pow_singleton;
+ case LShift:
+ Py_INCREF(state->LShift_singleton);
+ return state->LShift_singleton;
+ case RShift:
+ Py_INCREF(state->RShift_singleton);
+ return state->RShift_singleton;
+ case BitOr:
+ Py_INCREF(state->BitOr_singleton);
+ return state->BitOr_singleton;
+ case BitXor:
+ Py_INCREF(state->BitXor_singleton);
+ return state->BitXor_singleton;
+ case BitAnd:
+ Py_INCREF(state->BitAnd_singleton);
+ return state->BitAnd_singleton;
+ case FloorDiv:
+ Py_INCREF(state->FloorDiv_singleton);
+ return state->FloorDiv_singleton;
+ }
+ Py_UNREACHABLE();
+}
+PyObject* ast2obj_unaryop(astmodulestate *state, unaryop_ty o)
+{
+ switch(o) {
+ case Invert:
+ Py_INCREF(state->Invert_singleton);
+ return state->Invert_singleton;
+ case Not:
+ Py_INCREF(state->Not_singleton);
+ return state->Not_singleton;
+ case UAdd:
+ Py_INCREF(state->UAdd_singleton);
+ return state->UAdd_singleton;
+ case USub:
+ Py_INCREF(state->USub_singleton);
+ return state->USub_singleton;
+ }
+ Py_UNREACHABLE();
+}
+PyObject* ast2obj_cmpop(astmodulestate *state, cmpop_ty o)
+{
+ switch(o) {
+ case Eq:
+ Py_INCREF(state->Eq_singleton);
+ return state->Eq_singleton;
+ case NotEq:
+ Py_INCREF(state->NotEq_singleton);
+ return state->NotEq_singleton;
+ case Lt:
+ Py_INCREF(state->Lt_singleton);
+ return state->Lt_singleton;
+ case LtE:
+ Py_INCREF(state->LtE_singleton);
+ return state->LtE_singleton;
+ case Gt:
+ Py_INCREF(state->Gt_singleton);
+ return state->Gt_singleton;
+ case GtE:
+ Py_INCREF(state->GtE_singleton);
+ return state->GtE_singleton;
+ case Is:
+ Py_INCREF(state->Is_singleton);
+ return state->Is_singleton;
+ case IsNot:
+ Py_INCREF(state->IsNot_singleton);
+ return state->IsNot_singleton;
+ case In:
+ Py_INCREF(state->In_singleton);
+ return state->In_singleton;
+ case NotIn:
+ Py_INCREF(state->NotIn_singleton);
+ return state->NotIn_singleton;
+ }
+ Py_UNREACHABLE();
+}
+PyObject*
+ast2obj_comprehension(astmodulestate *state, void* _o)
+{
+ comprehension_ty o = (comprehension_ty)_o;
+ PyObject *result = NULL, *value = NULL;
+ PyTypeObject *tp;
+ if (!o) {
+ Py_RETURN_NONE;
+ }
+ tp = (PyTypeObject *)state->comprehension_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) return NULL;
+ value = ast2obj_expr(state, o->target);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->target, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->iter);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->iter, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->ifs, ast2obj_expr);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->ifs, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_int(state, o->is_async);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->is_async, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ return result;
+failed:
+ Py_XDECREF(value);
+ Py_XDECREF(result);
+ return NULL;
+}
+
+PyObject*
+ast2obj_excepthandler(astmodulestate *state, void* _o)
+{
+ excepthandler_ty o = (excepthandler_ty)_o;
+ PyObject *result = NULL, *value = NULL;
+ PyTypeObject *tp;
+ if (!o) {
+ Py_RETURN_NONE;
+ }
+ switch (o->kind) {
+ case ExceptHandler_kind:
+ tp = (PyTypeObject *)state->ExceptHandler_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.ExceptHandler.type);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->type, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_identifier(state, o->v.ExceptHandler.name);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->name, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->v.ExceptHandler.body, ast2obj_stmt);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->body, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ }
+ value = ast2obj_int(state, o->lineno);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->lineno, value) < 0)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_int(state, o->col_offset);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->col_offset, value) < 0)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_int(state, o->end_lineno);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->end_lineno, value) < 0)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_int(state, o->end_col_offset);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->end_col_offset, value) < 0)
+ goto failed;
+ Py_DECREF(value);
+ return result;
+failed:
+ Py_XDECREF(value);
+ Py_XDECREF(result);
+ return NULL;
+}
+
+PyObject*
+ast2obj_arguments(astmodulestate *state, void* _o)
+{
+ arguments_ty o = (arguments_ty)_o;
+ PyObject *result = NULL, *value = NULL;
+ PyTypeObject *tp;
+ if (!o) {
+ Py_RETURN_NONE;
+ }
+ tp = (PyTypeObject *)state->arguments_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) return NULL;
+ value = ast2obj_list(state, o->posonlyargs, ast2obj_arg);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->posonlyargs, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->args, ast2obj_arg);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->args, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_arg(state, o->vararg);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->vararg, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->kwonlyargs, ast2obj_arg);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->kwonlyargs, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->kw_defaults, ast2obj_expr);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->kw_defaults, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_arg(state, o->kwarg);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->kwarg, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(state, o->defaults, ast2obj_expr);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->defaults, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ return result;
+failed:
+ Py_XDECREF(value);
+ Py_XDECREF(result);
+ return NULL;
+}
+
+PyObject*
+ast2obj_arg(astmodulestate *state, void* _o)
+{
+ arg_ty o = (arg_ty)_o;
+ PyObject *result = NULL, *value = NULL;
+ PyTypeObject *tp;
+ if (!o) {
+ Py_RETURN_NONE;
+ }
+ tp = (PyTypeObject *)state->arg_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) return NULL;
+ value = ast2obj_identifier(state, o->arg);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->arg, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->annotation);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->annotation, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_string(state, o->type_comment);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->type_comment, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_int(state, o->lineno);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->lineno, value) < 0)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_int(state, o->col_offset);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->col_offset, value) < 0)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_int(state, o->end_lineno);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->end_lineno, value) < 0)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_int(state, o->end_col_offset);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->end_col_offset, value) < 0)
+ goto failed;
+ Py_DECREF(value);
+ return result;
+failed:
+ Py_XDECREF(value);
+ Py_XDECREF(result);
+ return NULL;
+}
+
+PyObject*
+ast2obj_keyword(astmodulestate *state, void* _o)
+{
+ keyword_ty o = (keyword_ty)_o;
+ PyObject *result = NULL, *value = NULL;
+ PyTypeObject *tp;
+ if (!o) {
+ Py_RETURN_NONE;
+ }
+ tp = (PyTypeObject *)state->keyword_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) return NULL;
+ value = ast2obj_identifier(state, o->arg);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->arg, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->value);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->value, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_int(state, o->lineno);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->lineno, value) < 0)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_int(state, o->col_offset);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->col_offset, value) < 0)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_int(state, o->end_lineno);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->end_lineno, value) < 0)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_int(state, o->end_col_offset);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->end_col_offset, value) < 0)
+ goto failed;
+ Py_DECREF(value);
+ return result;
+failed:
+ Py_XDECREF(value);
+ Py_XDECREF(result);
+ return NULL;
+}
+
+PyObject*
+ast2obj_alias(astmodulestate *state, void* _o)
+{
+ alias_ty o = (alias_ty)_o;
+ PyObject *result = NULL, *value = NULL;
+ PyTypeObject *tp;
+ if (!o) {
+ Py_RETURN_NONE;
+ }
+ tp = (PyTypeObject *)state->alias_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) return NULL;
+ value = ast2obj_identifier(state, o->name);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->name, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_identifier(state, o->asname);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->asname, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ return result;
+failed:
+ Py_XDECREF(value);
+ Py_XDECREF(result);
+ return NULL;
+}
+
+PyObject*
+ast2obj_withitem(astmodulestate *state, void* _o)
+{
+ withitem_ty o = (withitem_ty)_o;
+ PyObject *result = NULL, *value = NULL;
+ PyTypeObject *tp;
+ if (!o) {
+ Py_RETURN_NONE;
+ }
+ tp = (PyTypeObject *)state->withitem_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) return NULL;
+ value = ast2obj_expr(state, o->context_expr);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->context_expr, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->optional_vars);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->optional_vars, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ return result;
+failed:
+ Py_XDECREF(value);
+ Py_XDECREF(result);
+ return NULL;
+}
+
+PyObject*
+ast2obj_type_ignore(astmodulestate *state, void* _o)
+{
+ type_ignore_ty o = (type_ignore_ty)_o;
+ PyObject *result = NULL, *value = NULL;
+ PyTypeObject *tp;
+ if (!o) {
+ Py_RETURN_NONE;
+ }
+ switch (o->kind) {
+ case TypeIgnore_kind:
+ tp = (PyTypeObject *)state->TypeIgnore_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_int(state, o->v.TypeIgnore.lineno);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->lineno, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_string(state, o->v.TypeIgnore.tag);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->tag, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
+ }
+ return result;
+failed:
+ Py_XDECREF(value);
+ Py_XDECREF(result);
+ return NULL;
+}
+
+
+int
+obj2ast_mod(astmodulestate *state, PyObject* obj, mod_ty* out, PyArena* arena)
+{
+ int isinstance;
+
+ PyObject *tmp = NULL;
+ PyObject *tp;
+
+ if (obj == Py_None) {
+ *out = NULL;
+ return 0;
+ }
+ tp = state->Module_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ asdl_seq* body;
+ asdl_seq* type_ignores;
+
+ if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Module");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "Module field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ body = _Py_asdl_seq_new(len, arena);
+ if (body == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ stmt_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'Module' node")) {
+ goto failed;
+ }
+ res = obj2ast_stmt(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "Module field \"body\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(body, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->type_ignores, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"type_ignores\" missing from Module");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "Module field \"type_ignores\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ type_ignores = _Py_asdl_seq_new(len, arena);
+ if (type_ignores == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ type_ignore_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'Module' node")) {
+ goto failed;
+ }
+ res = obj2ast_type_ignore(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "Module field \"type_ignores\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(type_ignores, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ *out = Module(body, type_ignores, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Interactive_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ asdl_seq* body;
+
+ if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Interactive");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "Interactive field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ body = _Py_asdl_seq_new(len, arena);
+ if (body == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ stmt_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'Interactive' node")) {
+ goto failed;
+ }
+ res = obj2ast_stmt(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "Interactive field \"body\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(body, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ *out = Interactive(body, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Expression_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty body;
+
+ if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Expression");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Expression' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &body, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = Expression(body, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->FunctionType_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ asdl_seq* argtypes;
+ expr_ty returns;
+
+ if (_PyObject_LookupAttr(obj, state->argtypes, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"argtypes\" missing from FunctionType");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "FunctionType field \"argtypes\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ argtypes = _Py_asdl_seq_new(len, arena);
+ if (argtypes == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ expr_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'FunctionType' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "FunctionType field \"argtypes\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(argtypes, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->returns, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"returns\" missing from FunctionType");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'FunctionType' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &returns, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = FunctionType(argtypes, returns, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+
+ PyErr_Format(PyExc_TypeError, "expected some sort of mod, but got %R", obj);
+ failed:
+ Py_XDECREF(tmp);
+ return 1;
+}
+
+int
+obj2ast_stmt(astmodulestate *state, PyObject* obj, stmt_ty* out, PyArena* arena)
+{
+ int isinstance;
+
+ PyObject *tmp = NULL;
+ PyObject *tp;
+ int lineno;
+ int col_offset;
+ int end_lineno;
+ int end_col_offset;
+
+ if (obj == Py_None) {
+ *out = NULL;
+ return 0;
+ }
+ if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from stmt");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'stmt' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &lineno, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->col_offset, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from stmt");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'stmt' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &col_offset, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->end_lineno, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ end_lineno = 0;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'stmt' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &end_lineno, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->end_col_offset, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ end_col_offset = 0;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'stmt' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &end_col_offset, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ tp = state->FunctionDef_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ identifier name;
+ arguments_ty args;
+ asdl_seq* body;
+ asdl_seq* decorator_list;
+ expr_ty returns;
+ string type_comment;
+
+ if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from FunctionDef");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) {
+ goto failed;
+ }
+ res = obj2ast_identifier(state, tmp, &name, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->args, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from FunctionDef");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) {
+ goto failed;
+ }
+ res = obj2ast_arguments(state, tmp, &args, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from FunctionDef");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "FunctionDef field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ body = _Py_asdl_seq_new(len, arena);
+ if (body == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ stmt_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) {
+ goto failed;
+ }
+ res = obj2ast_stmt(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "FunctionDef field \"body\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(body, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->decorator_list, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"decorator_list\" missing from FunctionDef");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "FunctionDef field \"decorator_list\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ decorator_list = _Py_asdl_seq_new(len, arena);
+ if (decorator_list == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ expr_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "FunctionDef field \"decorator_list\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(decorator_list, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->returns, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ returns = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &returns, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ type_comment = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) {
+ goto failed;
+ }
+ res = obj2ast_string(state, tmp, &type_comment, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = FunctionDef(name, args, body, decorator_list, returns,
+ type_comment, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->AsyncFunctionDef_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ identifier name;
+ arguments_ty args;
+ asdl_seq* body;
+ asdl_seq* decorator_list;
+ expr_ty returns;
+ string type_comment;
+
+ if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from AsyncFunctionDef");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) {
+ goto failed;
+ }
+ res = obj2ast_identifier(state, tmp, &name, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->args, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from AsyncFunctionDef");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) {
+ goto failed;
+ }
+ res = obj2ast_arguments(state, tmp, &args, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from AsyncFunctionDef");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "AsyncFunctionDef field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ body = _Py_asdl_seq_new(len, arena);
+ if (body == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ stmt_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) {
+ goto failed;
+ }
+ res = obj2ast_stmt(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "AsyncFunctionDef field \"body\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(body, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->decorator_list, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"decorator_list\" missing from AsyncFunctionDef");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "AsyncFunctionDef field \"decorator_list\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ decorator_list = _Py_asdl_seq_new(len, arena);
+ if (decorator_list == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ expr_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "AsyncFunctionDef field \"decorator_list\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(decorator_list, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->returns, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ returns = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &returns, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ type_comment = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) {
+ goto failed;
+ }
+ res = obj2ast_string(state, tmp, &type_comment, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = AsyncFunctionDef(name, args, body, decorator_list, returns,
+ type_comment, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->ClassDef_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ identifier name;
+ asdl_seq* bases;
+ asdl_seq* keywords;
+ asdl_seq* body;
+ asdl_seq* decorator_list;
+
+ if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from ClassDef");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) {
+ goto failed;
+ }
+ res = obj2ast_identifier(state, tmp, &name, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->bases, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"bases\" missing from ClassDef");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "ClassDef field \"bases\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ bases = _Py_asdl_seq_new(len, arena);
+ if (bases == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ expr_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "ClassDef field \"bases\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(bases, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->keywords, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"keywords\" missing from ClassDef");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "ClassDef field \"keywords\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ keywords = _Py_asdl_seq_new(len, arena);
+ if (keywords == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ keyword_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) {
+ goto failed;
+ }
+ res = obj2ast_keyword(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "ClassDef field \"keywords\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(keywords, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from ClassDef");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "ClassDef field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ body = _Py_asdl_seq_new(len, arena);
+ if (body == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ stmt_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) {
+ goto failed;
+ }
+ res = obj2ast_stmt(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "ClassDef field \"body\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(body, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->decorator_list, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"decorator_list\" missing from ClassDef");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "ClassDef field \"decorator_list\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ decorator_list = _Py_asdl_seq_new(len, arena);
+ if (decorator_list == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ expr_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "ClassDef field \"decorator_list\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(decorator_list, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ *out = ClassDef(name, bases, keywords, body, decorator_list, lineno,
+ col_offset, end_lineno, end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Return_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty value;
+
+ if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ value = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Return' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &value, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = Return(value, lineno, col_offset, end_lineno, end_col_offset,
+ arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Delete_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ asdl_seq* targets;
+
+ if (_PyObject_LookupAttr(obj, state->targets, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"targets\" missing from Delete");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "Delete field \"targets\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ targets = _Py_asdl_seq_new(len, arena);
+ if (targets == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ expr_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'Delete' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "Delete field \"targets\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(targets, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ *out = Delete(targets, lineno, col_offset, end_lineno, end_col_offset,
+ arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Assign_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ asdl_seq* targets;
+ expr_ty value;
+ string type_comment;
+
+ if (_PyObject_LookupAttr(obj, state->targets, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"targets\" missing from Assign");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "Assign field \"targets\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ targets = _Py_asdl_seq_new(len, arena);
+ if (targets == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ expr_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'Assign' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "Assign field \"targets\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(targets, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Assign");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Assign' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &value, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ type_comment = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Assign' node")) {
+ goto failed;
+ }
+ res = obj2ast_string(state, tmp, &type_comment, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = Assign(targets, value, type_comment, lineno, col_offset,
+ end_lineno, end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->AugAssign_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty target;
+ operator_ty op;
+ expr_ty value;
+
+ if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from AugAssign");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'AugAssign' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &target, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->op, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from AugAssign");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'AugAssign' node")) {
+ goto failed;
+ }
+ res = obj2ast_operator(state, tmp, &op, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from AugAssign");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'AugAssign' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &value, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = AugAssign(target, op, value, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->AnnAssign_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty target;
+ expr_ty annotation;
+ expr_ty value;
+ int simple;
+
+ if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from AnnAssign");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'AnnAssign' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &target, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->annotation, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"annotation\" missing from AnnAssign");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'AnnAssign' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &annotation, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ value = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'AnnAssign' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &value, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->simple, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"simple\" missing from AnnAssign");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'AnnAssign' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &simple, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = AnnAssign(target, annotation, value, simple, lineno, col_offset,
+ end_lineno, end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->For_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty target;
+ expr_ty iter;
+ asdl_seq* body;
+ asdl_seq* orelse;
+ string type_comment;
+
+ if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from For");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'For' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &target, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->iter, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"iter\" missing from For");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'For' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &iter, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from For");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "For field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ body = _Py_asdl_seq_new(len, arena);
+ if (body == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ stmt_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'For' node")) {
+ goto failed;
+ }
+ res = obj2ast_stmt(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "For field \"body\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(body, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->orelse, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from For");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "For field \"orelse\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ orelse = _Py_asdl_seq_new(len, arena);
+ if (orelse == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ stmt_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'For' node")) {
+ goto failed;
+ }
+ res = obj2ast_stmt(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "For field \"orelse\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(orelse, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ type_comment = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'For' node")) {
+ goto failed;
+ }
+ res = obj2ast_string(state, tmp, &type_comment, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = For(target, iter, body, orelse, type_comment, lineno,
+ col_offset, end_lineno, end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->AsyncFor_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty target;
+ expr_ty iter;
+ asdl_seq* body;
+ asdl_seq* orelse;
+ string type_comment;
+
+ if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from AsyncFor");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &target, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->iter, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"iter\" missing from AsyncFor");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &iter, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from AsyncFor");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "AsyncFor field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ body = _Py_asdl_seq_new(len, arena);
+ if (body == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ stmt_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) {
+ goto failed;
+ }
+ res = obj2ast_stmt(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "AsyncFor field \"body\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(body, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->orelse, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from AsyncFor");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "AsyncFor field \"orelse\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ orelse = _Py_asdl_seq_new(len, arena);
+ if (orelse == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ stmt_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) {
+ goto failed;
+ }
+ res = obj2ast_stmt(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "AsyncFor field \"orelse\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(orelse, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ type_comment = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) {
+ goto failed;
+ }
+ res = obj2ast_string(state, tmp, &type_comment, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = AsyncFor(target, iter, body, orelse, type_comment, lineno,
+ col_offset, end_lineno, end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->While_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty test;
+ asdl_seq* body;
+ asdl_seq* orelse;
+
+ if (_PyObject_LookupAttr(obj, state->test, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from While");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'While' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &test, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from While");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "While field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ body = _Py_asdl_seq_new(len, arena);
+ if (body == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ stmt_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'While' node")) {
+ goto failed;
+ }
+ res = obj2ast_stmt(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "While field \"body\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(body, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->orelse, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from While");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "While field \"orelse\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ orelse = _Py_asdl_seq_new(len, arena);
+ if (orelse == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ stmt_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'While' node")) {
+ goto failed;
+ }
+ res = obj2ast_stmt(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "While field \"orelse\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(orelse, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ *out = While(test, body, orelse, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->If_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty test;
+ asdl_seq* body;
+ asdl_seq* orelse;
+
+ if (_PyObject_LookupAttr(obj, state->test, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from If");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'If' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &test, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from If");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "If field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ body = _Py_asdl_seq_new(len, arena);
+ if (body == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ stmt_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'If' node")) {
+ goto failed;
+ }
+ res = obj2ast_stmt(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "If field \"body\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(body, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->orelse, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from If");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "If field \"orelse\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ orelse = _Py_asdl_seq_new(len, arena);
+ if (orelse == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ stmt_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'If' node")) {
+ goto failed;
+ }
+ res = obj2ast_stmt(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "If field \"orelse\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(orelse, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ *out = If(test, body, orelse, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->With_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ asdl_seq* items;
+ asdl_seq* body;
+ string type_comment;
+
+ if (_PyObject_LookupAttr(obj, state->items, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"items\" missing from With");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "With field \"items\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ items = _Py_asdl_seq_new(len, arena);
+ if (items == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ withitem_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'With' node")) {
+ goto failed;
+ }
+ res = obj2ast_withitem(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "With field \"items\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(items, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from With");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "With field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ body = _Py_asdl_seq_new(len, arena);
+ if (body == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ stmt_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'With' node")) {
+ goto failed;
+ }
+ res = obj2ast_stmt(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "With field \"body\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(body, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ type_comment = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'With' node")) {
+ goto failed;
+ }
+ res = obj2ast_string(state, tmp, &type_comment, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = With(items, body, type_comment, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->AsyncWith_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ asdl_seq* items;
+ asdl_seq* body;
+ string type_comment;
+
+ if (_PyObject_LookupAttr(obj, state->items, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"items\" missing from AsyncWith");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "AsyncWith field \"items\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ items = _Py_asdl_seq_new(len, arena);
+ if (items == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ withitem_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'AsyncWith' node")) {
+ goto failed;
+ }
+ res = obj2ast_withitem(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "AsyncWith field \"items\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(items, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from AsyncWith");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "AsyncWith field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ body = _Py_asdl_seq_new(len, arena);
+ if (body == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ stmt_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'AsyncWith' node")) {
+ goto failed;
+ }
+ res = obj2ast_stmt(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "AsyncWith field \"body\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(body, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ type_comment = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'AsyncWith' node")) {
+ goto failed;
+ }
+ res = obj2ast_string(state, tmp, &type_comment, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = AsyncWith(items, body, type_comment, lineno, col_offset,
+ end_lineno, end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Raise_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty exc;
+ expr_ty cause;
+
+ if (_PyObject_LookupAttr(obj, state->exc, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ exc = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Raise' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &exc, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->cause, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ cause = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Raise' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &cause, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = Raise(exc, cause, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Try_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ asdl_seq* body;
+ asdl_seq* handlers;
+ asdl_seq* orelse;
+ asdl_seq* finalbody;
+
+ if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Try");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "Try field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ body = _Py_asdl_seq_new(len, arena);
+ if (body == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ stmt_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'Try' node")) {
+ goto failed;
+ }
+ res = obj2ast_stmt(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "Try field \"body\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(body, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->handlers, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"handlers\" missing from Try");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "Try field \"handlers\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ handlers = _Py_asdl_seq_new(len, arena);
+ if (handlers == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ excepthandler_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'Try' node")) {
+ goto failed;
+ }
+ res = obj2ast_excepthandler(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "Try field \"handlers\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(handlers, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->orelse, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from Try");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "Try field \"orelse\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ orelse = _Py_asdl_seq_new(len, arena);
+ if (orelse == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ stmt_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'Try' node")) {
+ goto failed;
+ }
+ res = obj2ast_stmt(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "Try field \"orelse\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(orelse, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->finalbody, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"finalbody\" missing from Try");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "Try field \"finalbody\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ finalbody = _Py_asdl_seq_new(len, arena);
+ if (finalbody == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ stmt_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'Try' node")) {
+ goto failed;
+ }
+ res = obj2ast_stmt(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "Try field \"finalbody\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(finalbody, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ *out = Try(body, handlers, orelse, finalbody, lineno, col_offset,
+ end_lineno, end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Assert_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty test;
+ expr_ty msg;
+
+ if (_PyObject_LookupAttr(obj, state->test, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from Assert");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Assert' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &test, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->msg, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ msg = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Assert' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &msg, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = Assert(test, msg, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Import_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ asdl_seq* names;
+
+ if (_PyObject_LookupAttr(obj, state->names, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"names\" missing from Import");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "Import field \"names\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ names = _Py_asdl_seq_new(len, arena);
+ if (names == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ alias_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'Import' node")) {
+ goto failed;
+ }
+ res = obj2ast_alias(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "Import field \"names\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(names, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ *out = Import(names, lineno, col_offset, end_lineno, end_col_offset,
+ arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->ImportFrom_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ identifier module;
+ asdl_seq* names;
+ int level;
+
+ if (_PyObject_LookupAttr(obj, state->module, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ module = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'ImportFrom' node")) {
+ goto failed;
+ }
+ res = obj2ast_identifier(state, tmp, &module, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->names, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"names\" missing from ImportFrom");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "ImportFrom field \"names\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ names = _Py_asdl_seq_new(len, arena);
+ if (names == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ alias_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'ImportFrom' node")) {
+ goto failed;
+ }
+ res = obj2ast_alias(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "ImportFrom field \"names\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(names, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->level, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ level = 0;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'ImportFrom' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &level, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = ImportFrom(module, names, level, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Global_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ asdl_seq* names;
+
+ if (_PyObject_LookupAttr(obj, state->names, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"names\" missing from Global");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "Global field \"names\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ names = _Py_asdl_seq_new(len, arena);
+ if (names == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ identifier val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'Global' node")) {
+ goto failed;
+ }
+ res = obj2ast_identifier(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "Global field \"names\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(names, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ *out = Global(names, lineno, col_offset, end_lineno, end_col_offset,
+ arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Nonlocal_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ asdl_seq* names;
+
+ if (_PyObject_LookupAttr(obj, state->names, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"names\" missing from Nonlocal");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "Nonlocal field \"names\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ names = _Py_asdl_seq_new(len, arena);
+ if (names == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ identifier val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'Nonlocal' node")) {
+ goto failed;
+ }
+ res = obj2ast_identifier(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "Nonlocal field \"names\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(names, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ *out = Nonlocal(names, lineno, col_offset, end_lineno, end_col_offset,
+ arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Expr_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty value;
+
+ if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Expr");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Expr' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &value, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = Expr(value, lineno, col_offset, end_lineno, end_col_offset,
+ arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Pass_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+
+ *out = Pass(lineno, col_offset, end_lineno, end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Break_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+
+ *out = Break(lineno, col_offset, end_lineno, end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Continue_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+
+ *out = Continue(lineno, col_offset, end_lineno, end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+
+ PyErr_Format(PyExc_TypeError, "expected some sort of stmt, but got %R", obj);
+ failed:
+ Py_XDECREF(tmp);
+ return 1;
+}
+
+int
+obj2ast_expr(astmodulestate *state, PyObject* obj, expr_ty* out, PyArena* arena)
+{
+ int isinstance;
+
+ PyObject *tmp = NULL;
+ PyObject *tp;
+ int lineno;
+ int col_offset;
+ int end_lineno;
+ int end_col_offset;
+
+ if (obj == Py_None) {
+ *out = NULL;
+ return 0;
+ }
+ if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from expr");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'expr' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &lineno, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->col_offset, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from expr");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'expr' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &col_offset, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->end_lineno, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ end_lineno = 0;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'expr' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &end_lineno, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->end_col_offset, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ end_col_offset = 0;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'expr' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &end_col_offset, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ tp = state->BoolOp_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ boolop_ty op;
+ asdl_seq* values;
+
+ if (_PyObject_LookupAttr(obj, state->op, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from BoolOp");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'BoolOp' node")) {
+ goto failed;
+ }
+ res = obj2ast_boolop(state, tmp, &op, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->values, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"values\" missing from BoolOp");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "BoolOp field \"values\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ values = _Py_asdl_seq_new(len, arena);
+ if (values == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ expr_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'BoolOp' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "BoolOp field \"values\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(values, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ *out = BoolOp(op, values, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->NamedExpr_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty target;
+ expr_ty value;
+
+ if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from NamedExpr");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'NamedExpr' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &target, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from NamedExpr");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'NamedExpr' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &value, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = NamedExpr(target, value, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->BinOp_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty left;
+ operator_ty op;
+ expr_ty right;
+
+ if (_PyObject_LookupAttr(obj, state->left, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"left\" missing from BinOp");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'BinOp' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &left, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->op, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from BinOp");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'BinOp' node")) {
+ goto failed;
+ }
+ res = obj2ast_operator(state, tmp, &op, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->right, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"right\" missing from BinOp");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'BinOp' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &right, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = BinOp(left, op, right, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->UnaryOp_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ unaryop_ty op;
+ expr_ty operand;
+
+ if (_PyObject_LookupAttr(obj, state->op, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from UnaryOp");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'UnaryOp' node")) {
+ goto failed;
+ }
+ res = obj2ast_unaryop(state, tmp, &op, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->operand, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"operand\" missing from UnaryOp");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'UnaryOp' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &operand, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = UnaryOp(op, operand, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Lambda_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ arguments_ty args;
+ expr_ty body;
+
+ if (_PyObject_LookupAttr(obj, state->args, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from Lambda");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Lambda' node")) {
+ goto failed;
+ }
+ res = obj2ast_arguments(state, tmp, &args, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Lambda");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Lambda' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &body, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = Lambda(args, body, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->IfExp_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty test;
+ expr_ty body;
+ expr_ty orelse;
+
+ if (_PyObject_LookupAttr(obj, state->test, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from IfExp");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'IfExp' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &test, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from IfExp");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'IfExp' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &body, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->orelse, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from IfExp");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'IfExp' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &orelse, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = IfExp(test, body, orelse, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Dict_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ asdl_seq* keys;
+ asdl_seq* values;
+
+ if (_PyObject_LookupAttr(obj, state->keys, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"keys\" missing from Dict");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "Dict field \"keys\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ keys = _Py_asdl_seq_new(len, arena);
+ if (keys == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ expr_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'Dict' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "Dict field \"keys\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(keys, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->values, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"values\" missing from Dict");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "Dict field \"values\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ values = _Py_asdl_seq_new(len, arena);
+ if (values == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ expr_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'Dict' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "Dict field \"values\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(values, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ *out = Dict(keys, values, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Set_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ asdl_seq* elts;
+
+ if (_PyObject_LookupAttr(obj, state->elts, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"elts\" missing from Set");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "Set field \"elts\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ elts = _Py_asdl_seq_new(len, arena);
+ if (elts == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ expr_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'Set' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "Set field \"elts\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(elts, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ *out = Set(elts, lineno, col_offset, end_lineno, end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->ListComp_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty elt;
+ asdl_seq* generators;
+
+ if (_PyObject_LookupAttr(obj, state->elt, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"elt\" missing from ListComp");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'ListComp' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &elt, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->generators, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"generators\" missing from ListComp");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "ListComp field \"generators\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ generators = _Py_asdl_seq_new(len, arena);
+ if (generators == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ comprehension_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'ListComp' node")) {
+ goto failed;
+ }
+ res = obj2ast_comprehension(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "ListComp field \"generators\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(generators, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ *out = ListComp(elt, generators, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->SetComp_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty elt;
+ asdl_seq* generators;
+
+ if (_PyObject_LookupAttr(obj, state->elt, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"elt\" missing from SetComp");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'SetComp' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &elt, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->generators, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"generators\" missing from SetComp");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "SetComp field \"generators\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ generators = _Py_asdl_seq_new(len, arena);
+ if (generators == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ comprehension_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'SetComp' node")) {
+ goto failed;
+ }
+ res = obj2ast_comprehension(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "SetComp field \"generators\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(generators, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ *out = SetComp(elt, generators, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->DictComp_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty key;
+ expr_ty value;
+ asdl_seq* generators;
+
+ if (_PyObject_LookupAttr(obj, state->key, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"key\" missing from DictComp");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'DictComp' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &key, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from DictComp");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'DictComp' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &value, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->generators, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"generators\" missing from DictComp");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "DictComp field \"generators\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ generators = _Py_asdl_seq_new(len, arena);
+ if (generators == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ comprehension_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'DictComp' node")) {
+ goto failed;
+ }
+ res = obj2ast_comprehension(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "DictComp field \"generators\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(generators, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ *out = DictComp(key, value, generators, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->GeneratorExp_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty elt;
+ asdl_seq* generators;
+
+ if (_PyObject_LookupAttr(obj, state->elt, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"elt\" missing from GeneratorExp");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'GeneratorExp' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &elt, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->generators, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"generators\" missing from GeneratorExp");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "GeneratorExp field \"generators\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ generators = _Py_asdl_seq_new(len, arena);
+ if (generators == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ comprehension_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'GeneratorExp' node")) {
+ goto failed;
+ }
+ res = obj2ast_comprehension(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "GeneratorExp field \"generators\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(generators, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ *out = GeneratorExp(elt, generators, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Await_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty value;
+
+ if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Await");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Await' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &value, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = Await(value, lineno, col_offset, end_lineno, end_col_offset,
+ arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Yield_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty value;
+
+ if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ value = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Yield' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &value, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = Yield(value, lineno, col_offset, end_lineno, end_col_offset,
+ arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->YieldFrom_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty value;
+
+ if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from YieldFrom");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'YieldFrom' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &value, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = YieldFrom(value, lineno, col_offset, end_lineno, end_col_offset,
+ arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Compare_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty left;
+ asdl_int_seq* ops;
+ asdl_seq* comparators;
+
+ if (_PyObject_LookupAttr(obj, state->left, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"left\" missing from Compare");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Compare' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &left, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->ops, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"ops\" missing from Compare");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "Compare field \"ops\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ ops = _Py_asdl_int_seq_new(len, arena);
+ if (ops == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ cmpop_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'Compare' node")) {
+ goto failed;
+ }
+ res = obj2ast_cmpop(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "Compare field \"ops\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(ops, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->comparators, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"comparators\" missing from Compare");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "Compare field \"comparators\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ comparators = _Py_asdl_seq_new(len, arena);
+ if (comparators == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ expr_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'Compare' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "Compare field \"comparators\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(comparators, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ *out = Compare(left, ops, comparators, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Call_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty func;
+ asdl_seq* args;
+ asdl_seq* keywords;
+
+ if (_PyObject_LookupAttr(obj, state->func, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"func\" missing from Call");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Call' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &func, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->args, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from Call");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "Call field \"args\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ args = _Py_asdl_seq_new(len, arena);
+ if (args == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ expr_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'Call' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "Call field \"args\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(args, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->keywords, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"keywords\" missing from Call");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "Call field \"keywords\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ keywords = _Py_asdl_seq_new(len, arena);
+ if (keywords == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ keyword_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'Call' node")) {
+ goto failed;
+ }
+ res = obj2ast_keyword(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "Call field \"keywords\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(keywords, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ *out = Call(func, args, keywords, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->FormattedValue_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty value;
+ int conversion;
+ expr_ty format_spec;
+
+ if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from FormattedValue");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'FormattedValue' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &value, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->conversion, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ conversion = 0;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'FormattedValue' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &conversion, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->format_spec, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ format_spec = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'FormattedValue' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &format_spec, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = FormattedValue(value, conversion, format_spec, lineno,
+ col_offset, end_lineno, end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->JoinedStr_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ asdl_seq* values;
+
+ if (_PyObject_LookupAttr(obj, state->values, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"values\" missing from JoinedStr");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "JoinedStr field \"values\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ values = _Py_asdl_seq_new(len, arena);
+ if (values == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ expr_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'JoinedStr' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "JoinedStr field \"values\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(values, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ *out = JoinedStr(values, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Constant_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ constant value;
+ string kind;
+
+ if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Constant");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Constant' node")) {
+ goto failed;
+ }
+ res = obj2ast_constant(state, tmp, &value, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->kind, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ kind = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Constant' node")) {
+ goto failed;
+ }
+ res = obj2ast_string(state, tmp, &kind, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = Constant(value, kind, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Attribute_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty value;
+ identifier attr;
+ expr_context_ty ctx;
+
+ if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Attribute");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Attribute' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &value, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->attr, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"attr\" missing from Attribute");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Attribute' node")) {
+ goto failed;
+ }
+ res = obj2ast_identifier(state, tmp, &attr, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->ctx, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Attribute");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Attribute' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr_context(state, tmp, &ctx, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = Attribute(value, attr, ctx, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Subscript_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty value;
+ expr_ty slice;
+ expr_context_ty ctx;
+
+ if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Subscript");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Subscript' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &value, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->slice, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"slice\" missing from Subscript");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Subscript' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &slice, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->ctx, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Subscript");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Subscript' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr_context(state, tmp, &ctx, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = Subscript(value, slice, ctx, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Starred_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty value;
+ expr_context_ty ctx;
+
+ if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Starred");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Starred' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &value, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->ctx, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Starred");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Starred' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr_context(state, tmp, &ctx, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = Starred(value, ctx, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Name_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ identifier id;
+ expr_context_ty ctx;
+
+ if (_PyObject_LookupAttr(obj, state->id, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"id\" missing from Name");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Name' node")) {
+ goto failed;
+ }
+ res = obj2ast_identifier(state, tmp, &id, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->ctx, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Name");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Name' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr_context(state, tmp, &ctx, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = Name(id, ctx, lineno, col_offset, end_lineno, end_col_offset,
+ arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->List_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ asdl_seq* elts;
+ expr_context_ty ctx;
+
+ if (_PyObject_LookupAttr(obj, state->elts, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"elts\" missing from List");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "List field \"elts\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ elts = _Py_asdl_seq_new(len, arena);
+ if (elts == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ expr_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'List' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "List field \"elts\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(elts, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->ctx, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from List");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'List' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr_context(state, tmp, &ctx, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = List(elts, ctx, lineno, col_offset, end_lineno, end_col_offset,
+ arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Tuple_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ asdl_seq* elts;
+ expr_context_ty ctx;
+
+ if (_PyObject_LookupAttr(obj, state->elts, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"elts\" missing from Tuple");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "Tuple field \"elts\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ elts = _Py_asdl_seq_new(len, arena);
+ if (elts == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ expr_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'Tuple' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "Tuple field \"elts\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(elts, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->ctx, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Tuple");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Tuple' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr_context(state, tmp, &ctx, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = Tuple(elts, ctx, lineno, col_offset, end_lineno, end_col_offset,
+ arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+ tp = state->Slice_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty lower;
+ expr_ty upper;
+ expr_ty step;
+
+ if (_PyObject_LookupAttr(obj, state->lower, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ lower = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Slice' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &lower, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->upper, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ upper = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Slice' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &upper, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->step, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ step = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'Slice' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &step, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = Slice(lower, upper, step, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+
+ PyErr_Format(PyExc_TypeError, "expected some sort of expr, but got %R", obj);
+ failed:
+ Py_XDECREF(tmp);
+ return 1;
+}
+
+int
+obj2ast_expr_context(astmodulestate *state, PyObject* obj, expr_context_ty*
+ out, PyArena* arena)
+{
+ int isinstance;
+
+ isinstance = PyObject_IsInstance(obj, state->Load_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = Load;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->Store_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = Store;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->Del_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = Del;
+ return 0;
+ }
+
+ PyErr_Format(PyExc_TypeError, "expected some sort of expr_context, but got %R", obj);
+ return 1;
+}
+
+int
+obj2ast_boolop(astmodulestate *state, PyObject* obj, boolop_ty* out, PyArena*
+ arena)
+{
+ int isinstance;
+
+ isinstance = PyObject_IsInstance(obj, state->And_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = And;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->Or_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = Or;
+ return 0;
+ }
+
+ PyErr_Format(PyExc_TypeError, "expected some sort of boolop, but got %R", obj);
+ return 1;
+}
+
+int
+obj2ast_operator(astmodulestate *state, PyObject* obj, operator_ty* out,
+ PyArena* arena)
+{
+ int isinstance;
+
+ isinstance = PyObject_IsInstance(obj, state->Add_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = Add;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->Sub_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = Sub;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->Mult_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = Mult;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->MatMult_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = MatMult;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->Div_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = Div;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->Mod_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = Mod;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->Pow_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = Pow;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->LShift_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = LShift;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->RShift_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = RShift;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->BitOr_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = BitOr;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->BitXor_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = BitXor;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->BitAnd_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = BitAnd;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->FloorDiv_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = FloorDiv;
+ return 0;
+ }
+
+ PyErr_Format(PyExc_TypeError, "expected some sort of operator, but got %R", obj);
+ return 1;
+}
+
+int
+obj2ast_unaryop(astmodulestate *state, PyObject* obj, unaryop_ty* out, PyArena*
+ arena)
+{
+ int isinstance;
+
+ isinstance = PyObject_IsInstance(obj, state->Invert_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = Invert;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->Not_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = Not;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->UAdd_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = UAdd;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->USub_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = USub;
+ return 0;
+ }
+
+ PyErr_Format(PyExc_TypeError, "expected some sort of unaryop, but got %R", obj);
+ return 1;
+}
+
+int
+obj2ast_cmpop(astmodulestate *state, PyObject* obj, cmpop_ty* out, PyArena*
+ arena)
+{
+ int isinstance;
+
+ isinstance = PyObject_IsInstance(obj, state->Eq_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = Eq;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->NotEq_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = NotEq;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->Lt_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = Lt;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->LtE_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = LtE;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->Gt_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = Gt;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->GtE_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = GtE;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->Is_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = Is;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->IsNot_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = IsNot;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->In_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = In;
+ return 0;
+ }
+ isinstance = PyObject_IsInstance(obj, state->NotIn_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = NotIn;
+ return 0;
+ }
+
+ PyErr_Format(PyExc_TypeError, "expected some sort of cmpop, but got %R", obj);
+ return 1;
+}
+
+int
+obj2ast_comprehension(astmodulestate *state, PyObject* obj, comprehension_ty*
+ out, PyArena* arena)
+{
+ PyObject* tmp = NULL;
+ expr_ty target;
+ expr_ty iter;
+ asdl_seq* ifs;
+ int is_async;
+
+ if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from comprehension");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'comprehension' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &target, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->iter, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"iter\" missing from comprehension");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'comprehension' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &iter, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->ifs, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"ifs\" missing from comprehension");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "comprehension field \"ifs\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ ifs = _Py_asdl_seq_new(len, arena);
+ if (ifs == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ expr_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'comprehension' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "comprehension field \"ifs\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(ifs, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->is_async, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"is_async\" missing from comprehension");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'comprehension' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &is_async, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = comprehension(target, iter, ifs, is_async, arena);
+ return 0;
+failed:
+ Py_XDECREF(tmp);
+ return 1;
+}
+
+int
+obj2ast_excepthandler(astmodulestate *state, PyObject* obj, excepthandler_ty*
+ out, PyArena* arena)
+{
+ int isinstance;
+
+ PyObject *tmp = NULL;
+ PyObject *tp;
+ int lineno;
+ int col_offset;
+ int end_lineno;
+ int end_col_offset;
+
+ if (obj == Py_None) {
+ *out = NULL;
+ return 0;
+ }
+ if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from excepthandler");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'excepthandler' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &lineno, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->col_offset, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from excepthandler");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'excepthandler' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &col_offset, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->end_lineno, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ end_lineno = 0;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'excepthandler' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &end_lineno, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->end_col_offset, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ end_col_offset = 0;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'excepthandler' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &end_col_offset, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ tp = state->ExceptHandler_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ expr_ty type;
+ identifier name;
+ asdl_seq* body;
+
+ if (_PyObject_LookupAttr(obj, state->type, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ type = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'ExceptHandler' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &type, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ name = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'ExceptHandler' node")) {
+ goto failed;
+ }
+ res = obj2ast_identifier(state, tmp, &name, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from ExceptHandler");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "ExceptHandler field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ body = _Py_asdl_seq_new(len, arena);
+ if (body == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ stmt_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'ExceptHandler' node")) {
+ goto failed;
+ }
+ res = obj2ast_stmt(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "ExceptHandler field \"body\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(body, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ *out = ExceptHandler(type, name, body, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+
+ PyErr_Format(PyExc_TypeError, "expected some sort of excepthandler, but got %R", obj);
+ failed:
+ Py_XDECREF(tmp);
+ return 1;
+}
+
+int
+obj2ast_arguments(astmodulestate *state, PyObject* obj, arguments_ty* out,
+ PyArena* arena)
+{
+ PyObject* tmp = NULL;
+ asdl_seq* posonlyargs;
+ asdl_seq* args;
+ arg_ty vararg;
+ asdl_seq* kwonlyargs;
+ asdl_seq* kw_defaults;
+ arg_ty kwarg;
+ asdl_seq* defaults;
+
+ if (_PyObject_LookupAttr(obj, state->posonlyargs, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"posonlyargs\" missing from arguments");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "arguments field \"posonlyargs\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ posonlyargs = _Py_asdl_seq_new(len, arena);
+ if (posonlyargs == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ arg_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'arguments' node")) {
+ goto failed;
+ }
+ res = obj2ast_arg(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "arguments field \"posonlyargs\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(posonlyargs, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->args, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from arguments");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "arguments field \"args\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ args = _Py_asdl_seq_new(len, arena);
+ if (args == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ arg_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'arguments' node")) {
+ goto failed;
+ }
+ res = obj2ast_arg(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "arguments field \"args\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(args, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->vararg, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ vararg = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'arguments' node")) {
+ goto failed;
+ }
+ res = obj2ast_arg(state, tmp, &vararg, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->kwonlyargs, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"kwonlyargs\" missing from arguments");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "arguments field \"kwonlyargs\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ kwonlyargs = _Py_asdl_seq_new(len, arena);
+ if (kwonlyargs == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ arg_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'arguments' node")) {
+ goto failed;
+ }
+ res = obj2ast_arg(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "arguments field \"kwonlyargs\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(kwonlyargs, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->kw_defaults, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"kw_defaults\" missing from arguments");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "arguments field \"kw_defaults\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ kw_defaults = _Py_asdl_seq_new(len, arena);
+ if (kw_defaults == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ expr_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'arguments' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "arguments field \"kw_defaults\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(kw_defaults, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->kwarg, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ kwarg = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'arguments' node")) {
+ goto failed;
+ }
+ res = obj2ast_arg(state, tmp, &kwarg, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->defaults, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"defaults\" missing from arguments");
+ return 1;
+ }
+ else {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "arguments field \"defaults\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ defaults = _Py_asdl_seq_new(len, arena);
+ if (defaults == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ expr_ty val;
+ PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
+ Py_INCREF(tmp2);
+ if (Py_EnterRecursiveCall(" while traversing 'arguments' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp2, &val, arena);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(tmp2);
+ if (res != 0) goto failed;
+ if (len != PyList_GET_SIZE(tmp)) {
+ PyErr_SetString(PyExc_RuntimeError, "arguments field \"defaults\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(defaults, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ *out = arguments(posonlyargs, args, vararg, kwonlyargs, kw_defaults, kwarg,
+ defaults, arena);
+ return 0;
+failed:
+ Py_XDECREF(tmp);
+ return 1;
+}
+
+int
+obj2ast_arg(astmodulestate *state, PyObject* obj, arg_ty* out, PyArena* arena)
+{
+ PyObject* tmp = NULL;
+ identifier arg;
+ expr_ty annotation;
+ string type_comment;
+ int lineno;
+ int col_offset;
+ int end_lineno;
+ int end_col_offset;
+
+ if (_PyObject_LookupAttr(obj, state->arg, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"arg\" missing from arg");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'arg' node")) {
+ goto failed;
+ }
+ res = obj2ast_identifier(state, tmp, &arg, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->annotation, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ annotation = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'arg' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &annotation, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ type_comment = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'arg' node")) {
+ goto failed;
+ }
+ res = obj2ast_string(state, tmp, &type_comment, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from arg");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'arg' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &lineno, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->col_offset, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from arg");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'arg' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &col_offset, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->end_lineno, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ end_lineno = 0;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'arg' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &end_lineno, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->end_col_offset, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ end_col_offset = 0;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'arg' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &end_col_offset, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = arg(arg, annotation, type_comment, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
+ return 0;
+failed:
+ Py_XDECREF(tmp);
+ return 1;
+}
+
+int
+obj2ast_keyword(astmodulestate *state, PyObject* obj, keyword_ty* out, PyArena*
+ arena)
+{
+ PyObject* tmp = NULL;
+ identifier arg;
+ expr_ty value;
+ int lineno;
+ int col_offset;
+ int end_lineno;
+ int end_col_offset;
+
+ if (_PyObject_LookupAttr(obj, state->arg, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ arg = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'keyword' node")) {
+ goto failed;
+ }
+ res = obj2ast_identifier(state, tmp, &arg, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from keyword");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'keyword' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &value, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from keyword");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'keyword' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &lineno, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->col_offset, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from keyword");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'keyword' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &col_offset, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->end_lineno, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ end_lineno = 0;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'keyword' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &end_lineno, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->end_col_offset, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ end_col_offset = 0;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'keyword' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &end_col_offset, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = keyword(arg, value, lineno, col_offset, end_lineno, end_col_offset,
+ arena);
+ return 0;
+failed:
+ Py_XDECREF(tmp);
+ return 1;
+}
+
+int
+obj2ast_alias(astmodulestate *state, PyObject* obj, alias_ty* out, PyArena*
+ arena)
+{
+ PyObject* tmp = NULL;
+ identifier name;
+ identifier asname;
+
+ if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from alias");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'alias' node")) {
+ goto failed;
+ }
+ res = obj2ast_identifier(state, tmp, &name, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->asname, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ asname = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'alias' node")) {
+ goto failed;
+ }
+ res = obj2ast_identifier(state, tmp, &asname, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = alias(name, asname, arena);
+ return 0;
+failed:
+ Py_XDECREF(tmp);
+ return 1;
+}
+
+int
+obj2ast_withitem(astmodulestate *state, PyObject* obj, withitem_ty* out,
+ PyArena* arena)
+{
+ PyObject* tmp = NULL;
+ expr_ty context_expr;
+ expr_ty optional_vars;
+
+ if (_PyObject_LookupAttr(obj, state->context_expr, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"context_expr\" missing from withitem");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'withitem' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &context_expr, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->optional_vars, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ optional_vars = NULL;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'withitem' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &optional_vars, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = withitem(context_expr, optional_vars, arena);
+ return 0;
+failed:
+ Py_XDECREF(tmp);
+ return 1;
+}
+
+int
+obj2ast_type_ignore(astmodulestate *state, PyObject* obj, type_ignore_ty* out,
+ PyArena* arena)
+{
+ int isinstance;
+
+ PyObject *tmp = NULL;
+ PyObject *tp;
+
+ if (obj == Py_None) {
+ *out = NULL;
+ return 0;
+ }
+ tp = state->TypeIgnore_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ int lineno;
+ string tag;
+
+ if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from TypeIgnore");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'TypeIgnore' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &lineno, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (_PyObject_LookupAttr(obj, state->tag, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"tag\" missing from TypeIgnore");
+ return 1;
+ }
+ else {
+ int res;
+ if (Py_EnterRecursiveCall(" while traversing 'TypeIgnore' node")) {
+ goto failed;
+ }
+ res = obj2ast_string(state, tmp, &tag, arena);
+ Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = TypeIgnore(lineno, tag, arena);
+ if (*out == NULL) goto failed;
+ return 0;
+ }
+
+ PyErr_Format(PyExc_TypeError, "expected some sort of type_ignore, but got %R", obj);
+ failed:
+ Py_XDECREF(tmp);
+ return 1;
+}
+
+
+static int
+astmodule_exec(PyObject *m)
+{
+ astmodulestate *state = get_ast_state(m);
+
+ if (!init_types(state)) {
+ return -1;
+ }
+ if (PyModule_AddObject(m, "AST", state->AST_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->AST_type);
+ if (PyModule_AddIntMacro(m, PyCF_ALLOW_TOP_LEVEL_AWAIT) < 0) {
+ return -1;
+ }
+ if (PyModule_AddIntMacro(m, PyCF_ONLY_AST) < 0) {
+ return -1;
+ }
+ if (PyModule_AddIntMacro(m, PyCF_TYPE_COMMENTS) < 0) {
+ return -1;
+ }
+ if (PyModule_AddObject(m, "mod", state->mod_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->mod_type);
+ if (PyModule_AddObject(m, "Module", state->Module_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Module_type);
+ if (PyModule_AddObject(m, "Interactive", state->Interactive_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Interactive_type);
+ if (PyModule_AddObject(m, "Expression", state->Expression_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Expression_type);
+ if (PyModule_AddObject(m, "FunctionType", state->FunctionType_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->FunctionType_type);
+ if (PyModule_AddObject(m, "stmt", state->stmt_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->stmt_type);
+ if (PyModule_AddObject(m, "FunctionDef", state->FunctionDef_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->FunctionDef_type);
+ if (PyModule_AddObject(m, "AsyncFunctionDef", state->AsyncFunctionDef_type)
+ < 0) {
+ return -1;
+ }
+ Py_INCREF(state->AsyncFunctionDef_type);
+ if (PyModule_AddObject(m, "ClassDef", state->ClassDef_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->ClassDef_type);
+ if (PyModule_AddObject(m, "Return", state->Return_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Return_type);
+ if (PyModule_AddObject(m, "Delete", state->Delete_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Delete_type);
+ if (PyModule_AddObject(m, "Assign", state->Assign_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Assign_type);
+ if (PyModule_AddObject(m, "AugAssign", state->AugAssign_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->AugAssign_type);
+ if (PyModule_AddObject(m, "AnnAssign", state->AnnAssign_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->AnnAssign_type);
+ if (PyModule_AddObject(m, "For", state->For_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->For_type);
+ if (PyModule_AddObject(m, "AsyncFor", state->AsyncFor_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->AsyncFor_type);
+ if (PyModule_AddObject(m, "While", state->While_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->While_type);
+ if (PyModule_AddObject(m, "If", state->If_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->If_type);
+ if (PyModule_AddObject(m, "With", state->With_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->With_type);
+ if (PyModule_AddObject(m, "AsyncWith", state->AsyncWith_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->AsyncWith_type);
+ if (PyModule_AddObject(m, "Raise", state->Raise_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Raise_type);
+ if (PyModule_AddObject(m, "Try", state->Try_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Try_type);
+ if (PyModule_AddObject(m, "Assert", state->Assert_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Assert_type);
+ if (PyModule_AddObject(m, "Import", state->Import_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Import_type);
+ if (PyModule_AddObject(m, "ImportFrom", state->ImportFrom_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->ImportFrom_type);
+ if (PyModule_AddObject(m, "Global", state->Global_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Global_type);
+ if (PyModule_AddObject(m, "Nonlocal", state->Nonlocal_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Nonlocal_type);
+ if (PyModule_AddObject(m, "Expr", state->Expr_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Expr_type);
+ if (PyModule_AddObject(m, "Pass", state->Pass_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Pass_type);
+ if (PyModule_AddObject(m, "Break", state->Break_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Break_type);
+ if (PyModule_AddObject(m, "Continue", state->Continue_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Continue_type);
+ if (PyModule_AddObject(m, "expr", state->expr_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->expr_type);
+ if (PyModule_AddObject(m, "BoolOp", state->BoolOp_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->BoolOp_type);
+ if (PyModule_AddObject(m, "NamedExpr", state->NamedExpr_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->NamedExpr_type);
+ if (PyModule_AddObject(m, "BinOp", state->BinOp_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->BinOp_type);
+ if (PyModule_AddObject(m, "UnaryOp", state->UnaryOp_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->UnaryOp_type);
+ if (PyModule_AddObject(m, "Lambda", state->Lambda_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Lambda_type);
+ if (PyModule_AddObject(m, "IfExp", state->IfExp_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->IfExp_type);
+ if (PyModule_AddObject(m, "Dict", state->Dict_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Dict_type);
+ if (PyModule_AddObject(m, "Set", state->Set_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Set_type);
+ if (PyModule_AddObject(m, "ListComp", state->ListComp_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->ListComp_type);
+ if (PyModule_AddObject(m, "SetComp", state->SetComp_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->SetComp_type);
+ if (PyModule_AddObject(m, "DictComp", state->DictComp_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->DictComp_type);
+ if (PyModule_AddObject(m, "GeneratorExp", state->GeneratorExp_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->GeneratorExp_type);
+ if (PyModule_AddObject(m, "Await", state->Await_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Await_type);
+ if (PyModule_AddObject(m, "Yield", state->Yield_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Yield_type);
+ if (PyModule_AddObject(m, "YieldFrom", state->YieldFrom_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->YieldFrom_type);
+ if (PyModule_AddObject(m, "Compare", state->Compare_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Compare_type);
+ if (PyModule_AddObject(m, "Call", state->Call_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Call_type);
+ if (PyModule_AddObject(m, "FormattedValue", state->FormattedValue_type) <
+ 0) {
+ return -1;
+ }
+ Py_INCREF(state->FormattedValue_type);
+ if (PyModule_AddObject(m, "JoinedStr", state->JoinedStr_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->JoinedStr_type);
+ if (PyModule_AddObject(m, "Constant", state->Constant_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Constant_type);
+ if (PyModule_AddObject(m, "Attribute", state->Attribute_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Attribute_type);
+ if (PyModule_AddObject(m, "Subscript", state->Subscript_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Subscript_type);
+ if (PyModule_AddObject(m, "Starred", state->Starred_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Starred_type);
+ if (PyModule_AddObject(m, "Name", state->Name_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Name_type);
+ if (PyModule_AddObject(m, "List", state->List_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->List_type);
+ if (PyModule_AddObject(m, "Tuple", state->Tuple_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Tuple_type);
+ if (PyModule_AddObject(m, "Slice", state->Slice_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Slice_type);
+ if (PyModule_AddObject(m, "expr_context", state->expr_context_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->expr_context_type);
+ if (PyModule_AddObject(m, "Load", state->Load_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Load_type);
+ if (PyModule_AddObject(m, "Store", state->Store_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Store_type);
+ if (PyModule_AddObject(m, "Del", state->Del_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Del_type);
+ if (PyModule_AddObject(m, "boolop", state->boolop_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->boolop_type);
+ if (PyModule_AddObject(m, "And", state->And_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->And_type);
+ if (PyModule_AddObject(m, "Or", state->Or_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Or_type);
+ if (PyModule_AddObject(m, "operator", state->operator_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->operator_type);
+ if (PyModule_AddObject(m, "Add", state->Add_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Add_type);
+ if (PyModule_AddObject(m, "Sub", state->Sub_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Sub_type);
+ if (PyModule_AddObject(m, "Mult", state->Mult_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Mult_type);
+ if (PyModule_AddObject(m, "MatMult", state->MatMult_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->MatMult_type);
+ if (PyModule_AddObject(m, "Div", state->Div_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Div_type);
+ if (PyModule_AddObject(m, "Mod", state->Mod_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Mod_type);
+ if (PyModule_AddObject(m, "Pow", state->Pow_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Pow_type);
+ if (PyModule_AddObject(m, "LShift", state->LShift_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->LShift_type);
+ if (PyModule_AddObject(m, "RShift", state->RShift_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->RShift_type);
+ if (PyModule_AddObject(m, "BitOr", state->BitOr_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->BitOr_type);
+ if (PyModule_AddObject(m, "BitXor", state->BitXor_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->BitXor_type);
+ if (PyModule_AddObject(m, "BitAnd", state->BitAnd_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->BitAnd_type);
+ if (PyModule_AddObject(m, "FloorDiv", state->FloorDiv_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->FloorDiv_type);
+ if (PyModule_AddObject(m, "unaryop", state->unaryop_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->unaryop_type);
+ if (PyModule_AddObject(m, "Invert", state->Invert_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Invert_type);
+ if (PyModule_AddObject(m, "Not", state->Not_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Not_type);
+ if (PyModule_AddObject(m, "UAdd", state->UAdd_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->UAdd_type);
+ if (PyModule_AddObject(m, "USub", state->USub_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->USub_type);
+ if (PyModule_AddObject(m, "cmpop", state->cmpop_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->cmpop_type);
+ if (PyModule_AddObject(m, "Eq", state->Eq_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Eq_type);
+ if (PyModule_AddObject(m, "NotEq", state->NotEq_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->NotEq_type);
+ if (PyModule_AddObject(m, "Lt", state->Lt_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Lt_type);
+ if (PyModule_AddObject(m, "LtE", state->LtE_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->LtE_type);
+ if (PyModule_AddObject(m, "Gt", state->Gt_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Gt_type);
+ if (PyModule_AddObject(m, "GtE", state->GtE_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->GtE_type);
+ if (PyModule_AddObject(m, "Is", state->Is_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->Is_type);
+ if (PyModule_AddObject(m, "IsNot", state->IsNot_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->IsNot_type);
+ if (PyModule_AddObject(m, "In", state->In_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->In_type);
+ if (PyModule_AddObject(m, "NotIn", state->NotIn_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->NotIn_type);
+ if (PyModule_AddObject(m, "comprehension", state->comprehension_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->comprehension_type);
+ if (PyModule_AddObject(m, "excepthandler", state->excepthandler_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->excepthandler_type);
+ if (PyModule_AddObject(m, "ExceptHandler", state->ExceptHandler_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->ExceptHandler_type);
+ if (PyModule_AddObject(m, "arguments", state->arguments_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->arguments_type);
+ if (PyModule_AddObject(m, "arg", state->arg_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->arg_type);
+ if (PyModule_AddObject(m, "keyword", state->keyword_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->keyword_type);
+ if (PyModule_AddObject(m, "alias", state->alias_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->alias_type);
+ if (PyModule_AddObject(m, "withitem", state->withitem_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->withitem_type);
+ if (PyModule_AddObject(m, "type_ignore", state->type_ignore_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->type_ignore_type);
+ if (PyModule_AddObject(m, "TypeIgnore", state->TypeIgnore_type) < 0) {
+ return -1;
+ }
+ Py_INCREF(state->TypeIgnore_type);
+ return 0;
+}
+
+static PyModuleDef_Slot astmodule_slots[] = {
+ {Py_mod_exec, astmodule_exec},
+ {0, NULL}
+};
+
+static struct PyModuleDef _astmodule = {
+ PyModuleDef_HEAD_INIT,
+ .m_name = "_ast",
+ // The _ast module uses a global state (global_ast_state).
+ .m_size = 0,
+ .m_slots = astmodule_slots,
+};
+
+PyMODINIT_FUNC
+PyInit__ast(void)
+{
+ return PyModuleDef_Init(&_astmodule);
+}
+
+
+PyObject* PyAST_mod2obj(mod_ty t)
+{
+ astmodulestate *state = get_global_ast_state();
+ if (state == NULL) {
+ return NULL;
+ }
+ return ast2obj_mod(state, t);
+}
+
+/* mode is 0 for "exec", 1 for "eval" and 2 for "single" input */
+mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode)
+{
+ const char * const req_name[] = {"Module", "Expression", "Interactive"};
+ int isinstance;
+
+ if (PySys_Audit("compile", "OO", ast, Py_None) < 0) {
+ return NULL;
+ }
+
+ astmodulestate *state = get_global_ast_state();
+ PyObject *req_type[3];
+ req_type[0] = state->Module_type;
+ req_type[1] = state->Expression_type;
+ req_type[2] = state->Interactive_type;
+
+ assert(0 <= mode && mode <= 2);
+
+ isinstance = PyObject_IsInstance(ast, req_type[mode]);
+ if (isinstance == -1)
+ return NULL;
+ if (!isinstance) {
+ PyErr_Format(PyExc_TypeError, "expected %s node, got %.400s",
+ req_name[mode], _PyType_Name(Py_TYPE(ast)));
+ return NULL;
+ }
+
+ mod_ty res = NULL;
+ if (obj2ast_mod(state, ast, &res, arena) != 0)
+ return NULL;
+ else
+ return res;
+}
+
+int PyAST_Check(PyObject* obj)
+{
+ astmodulestate *state = get_global_ast_state();
+ if (state == NULL) {
+ return -1;
+ }
+ return PyObject_IsInstance(obj, state->AST_type);
+}
+
+
diff --git a/contrib/tools/python3/src/Python/_warnings.c b/contrib/tools/python3/src/Python/_warnings.c
new file mode 100644
index 00000000000..91a78fe72b3
--- /dev/null
+++ b/contrib/tools/python3/src/Python/_warnings.c
@@ -0,0 +1,1430 @@
+#include "Python.h"
+#include "pycore_initconfig.h"
+#include "pycore_interp.h" // PyInterpreterState.warnings
+#include "pycore_pyerrors.h"
+#include "pycore_pystate.h" // _PyThreadState_GET()
+#include "frameobject.h" // PyFrame_GetBack()
+#include "clinic/_warnings.c.h"
+
+#define MODULE_NAME "_warnings"
+
+PyDoc_STRVAR(warnings__doc__,
+MODULE_NAME " provides basic warning filtering support.\n"
+"It is a helper module to speed up interpreter start-up.");
+
+_Py_IDENTIFIER(stderr);
+#ifndef Py_DEBUG
+_Py_IDENTIFIER(default);
+_Py_IDENTIFIER(ignore);
+#endif
+
+
+/*************************************************************************/
+
+typedef struct _warnings_runtime_state WarningsState;
+
+/* Forward declaration of the _warnings module definition. */
+static struct PyModuleDef warningsmodule;
+
+_Py_IDENTIFIER(__name__);
+
+/* Given a module object, get its per-module state. */
+static WarningsState *
+warnings_get_state(void)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (tstate == NULL) {
+ _PyErr_SetString(tstate, PyExc_RuntimeError,
+ "warnings_get_state: could not identify "
+ "current interpreter");
+ return NULL;
+ }
+ return &tstate->interp->warnings;
+}
+
+/* Clear the given warnings module state. */
+static void
+warnings_clear_state(WarningsState *st)
+{
+ Py_CLEAR(st->filters);
+ Py_CLEAR(st->once_registry);
+ Py_CLEAR(st->default_action);
+}
+
+#ifndef Py_DEBUG
+static PyObject *
+create_filter(PyObject *category, _Py_Identifier *id, const char *modname)
+{
+ PyObject *modname_obj = NULL;
+ PyObject *action_str = _PyUnicode_FromId(id);
+ if (action_str == NULL) {
+ return NULL;
+ }
+
+ /* Default to "no module name" for initial filter set */
+ if (modname != NULL) {
+ modname_obj = PyUnicode_InternFromString(modname);
+ if (modname_obj == NULL) {
+ return NULL;
+ }
+ } else {
+ modname_obj = Py_None;
+ Py_INCREF(modname_obj);
+ }
+
+ /* This assumes the line number is zero for now. */
+ PyObject *filter = PyTuple_Pack(5, action_str, Py_None,
+ category, modname_obj, _PyLong_Zero);
+ Py_DECREF(modname_obj);
+ return filter;
+}
+#endif
+
+static PyObject *
+init_filters(void)
+{
+#ifdef Py_DEBUG
+ /* Py_DEBUG builds show all warnings by default */
+ return PyList_New(0);
+#else
+ /* Other builds ignore a number of warning categories by default */
+ PyObject *filters = PyList_New(5);
+ if (filters == NULL) {
+ return NULL;
+ }
+
+ size_t pos = 0; /* Post-incremented in each use. */
+ PyList_SET_ITEM(filters, pos++,
+ create_filter(PyExc_DeprecationWarning, &PyId_default, "__main__"));
+ PyList_SET_ITEM(filters, pos++,
+ create_filter(PyExc_DeprecationWarning, &PyId_ignore, NULL));
+ PyList_SET_ITEM(filters, pos++,
+ create_filter(PyExc_PendingDeprecationWarning, &PyId_ignore, NULL));
+ PyList_SET_ITEM(filters, pos++,
+ create_filter(PyExc_ImportWarning, &PyId_ignore, NULL));
+ PyList_SET_ITEM(filters, pos++,
+ create_filter(PyExc_ResourceWarning, &PyId_ignore, NULL));
+
+ for (size_t x = 0; x < pos; x++) {
+ if (PyList_GET_ITEM(filters, x) == NULL) {
+ Py_DECREF(filters);
+ return NULL;
+ }
+ }
+ return filters;
+#endif
+}
+
+/* Initialize the given warnings module state. */
+static int
+warnings_init_state(WarningsState *st)
+{
+ if (st->filters == NULL) {
+ st->filters = init_filters();
+ if (st->filters == NULL) {
+ goto error;
+ }
+ }
+
+ if (st->once_registry == NULL) {
+ st->once_registry = PyDict_New();
+ if (st->once_registry == NULL) {
+ goto error;
+ }
+ }
+
+ if (st->default_action == NULL) {
+ st->default_action = PyUnicode_FromString("default");
+ if (st->default_action == NULL) {
+ goto error;
+ }
+ }
+
+ st->filters_version = 0;
+
+ return 0;
+
+error:
+ warnings_clear_state(st);
+ return -1;
+}
+
+
+/*************************************************************************/
+
+static int
+check_matched(PyObject *obj, PyObject *arg)
+{
+ PyObject *result;
+ _Py_IDENTIFIER(match);
+ int rc;
+
+ /* A 'None' filter always matches */
+ if (obj == Py_None)
+ return 1;
+
+ /* An internal plain text default filter must match exactly */
+ if (PyUnicode_CheckExact(obj)) {
+ int cmp_result = PyUnicode_Compare(obj, arg);
+ if (cmp_result == -1 && PyErr_Occurred()) {
+ return -1;
+ }
+ return !cmp_result;
+ }
+
+ /* Otherwise assume a regex filter and call its match() method */
+ result = _PyObject_CallMethodIdOneArg(obj, &PyId_match, arg);
+ if (result == NULL)
+ return -1;
+
+ rc = PyObject_IsTrue(result);
+ Py_DECREF(result);
+ return rc;
+}
+
+/*
+ Returns a new reference.
+ A NULL return value can mean false or an error.
+*/
+static PyObject *
+get_warnings_attr(_Py_Identifier *attr_id, int try_import)
+{
+ PyObject *warnings_str;
+ PyObject *warnings_module, *obj;
+ _Py_IDENTIFIER(warnings);
+
+ warnings_str = _PyUnicode_FromId(&PyId_warnings);
+ if (warnings_str == NULL) {
+ return NULL;
+ }
+
+ /* don't try to import after the start of the Python finallization */
+ if (try_import && !_Py_IsFinalizing()) {
+ warnings_module = PyImport_Import(warnings_str);
+ if (warnings_module == NULL) {
+ /* Fallback to the C implementation if we cannot get
+ the Python implementation */
+ if (PyErr_ExceptionMatches(PyExc_ImportError)) {
+ PyErr_Clear();
+ }
+ return NULL;
+ }
+ }
+ else {
+ /* if we're so late into Python finalization that the module dict is
+ gone, then we can't even use PyImport_GetModule without triggering
+ an interpreter abort.
+ */
+ if (!_PyInterpreterState_GET()->modules) {
+ return NULL;
+ }
+ warnings_module = PyImport_GetModule(warnings_str);
+ if (warnings_module == NULL)
+ return NULL;
+ }
+
+ (void)_PyObject_LookupAttrId(warnings_module, attr_id, &obj);
+ Py_DECREF(warnings_module);
+ return obj;
+}
+
+
+static PyObject *
+get_once_registry(WarningsState *st)
+{
+ PyObject *registry;
+ _Py_IDENTIFIER(onceregistry);
+
+ registry = get_warnings_attr(&PyId_onceregistry, 0);
+ if (registry == NULL) {
+ if (PyErr_Occurred())
+ return NULL;
+ assert(st->once_registry);
+ return st->once_registry;
+ }
+ if (!PyDict_Check(registry)) {
+ PyErr_Format(PyExc_TypeError,
+ MODULE_NAME ".onceregistry must be a dict, "
+ "not '%.200s'",
+ Py_TYPE(registry)->tp_name);
+ Py_DECREF(registry);
+ return NULL;
+ }
+ Py_SETREF(st->once_registry, registry);
+ return registry;
+}
+
+
+static PyObject *
+get_default_action(WarningsState *st)
+{
+ PyObject *default_action;
+ _Py_IDENTIFIER(defaultaction);
+
+ default_action = get_warnings_attr(&PyId_defaultaction, 0);
+ if (default_action == NULL) {
+ if (PyErr_Occurred()) {
+ return NULL;
+ }
+ assert(st->default_action);
+ return st->default_action;
+ }
+ if (!PyUnicode_Check(default_action)) {
+ PyErr_Format(PyExc_TypeError,
+ MODULE_NAME ".defaultaction must be a string, "
+ "not '%.200s'",
+ Py_TYPE(default_action)->tp_name);
+ Py_DECREF(default_action);
+ return NULL;
+ }
+ Py_SETREF(st->default_action, default_action);
+ return default_action;
+}
+
+
+/* The item is a new reference. */
+static PyObject*
+get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
+ PyObject *module, PyObject **item)
+{
+ PyObject *action;
+ Py_ssize_t i;
+ PyObject *warnings_filters;
+ _Py_IDENTIFIER(filters);
+ WarningsState *st = warnings_get_state();
+ if (st == NULL) {
+ return NULL;
+ }
+
+ warnings_filters = get_warnings_attr(&PyId_filters, 0);
+ if (warnings_filters == NULL) {
+ if (PyErr_Occurred())
+ return NULL;
+ }
+ else {
+ Py_SETREF(st->filters, warnings_filters);
+ }
+
+ PyObject *filters = st->filters;
+ if (filters == NULL || !PyList_Check(filters)) {
+ PyErr_SetString(PyExc_ValueError,
+ MODULE_NAME ".filters must be a list");
+ return NULL;
+ }
+
+ /* WarningsState.filters could change while we are iterating over it. */
+ for (i = 0; i < PyList_GET_SIZE(filters); i++) {
+ PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj;
+ Py_ssize_t ln;
+ int is_subclass, good_msg, good_mod;
+
+ tmp_item = PyList_GET_ITEM(filters, i);
+ if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) {
+ PyErr_Format(PyExc_ValueError,
+ MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
+ return NULL;
+ }
+
+ /* Python code: action, msg, cat, mod, ln = item */
+ Py_INCREF(tmp_item);
+ action = PyTuple_GET_ITEM(tmp_item, 0);
+ msg = PyTuple_GET_ITEM(tmp_item, 1);
+ cat = PyTuple_GET_ITEM(tmp_item, 2);
+ mod = PyTuple_GET_ITEM(tmp_item, 3);
+ ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
+
+ if (!PyUnicode_Check(action)) {
+ PyErr_Format(PyExc_TypeError,
+ "action must be a string, not '%.200s'",
+ Py_TYPE(action)->tp_name);
+ Py_DECREF(tmp_item);
+ return NULL;
+ }
+
+ good_msg = check_matched(msg, text);
+ if (good_msg == -1) {
+ Py_DECREF(tmp_item);
+ return NULL;
+ }
+
+ good_mod = check_matched(mod, module);
+ if (good_mod == -1) {
+ Py_DECREF(tmp_item);
+ return NULL;
+ }
+
+ is_subclass = PyObject_IsSubclass(category, cat);
+ if (is_subclass == -1) {
+ Py_DECREF(tmp_item);
+ return NULL;
+ }
+
+ ln = PyLong_AsSsize_t(ln_obj);
+ if (ln == -1 && PyErr_Occurred()) {
+ Py_DECREF(tmp_item);
+ return NULL;
+ }
+
+ if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) {
+ *item = tmp_item;
+ return action;
+ }
+
+ Py_DECREF(tmp_item);
+ }
+
+ action = get_default_action(st);
+ if (action != NULL) {
+ Py_INCREF(Py_None);
+ *item = Py_None;
+ return action;
+ }
+
+ return NULL;
+}
+
+
+static int
+already_warned(PyObject *registry, PyObject *key, int should_set)
+{
+ PyObject *version_obj, *already_warned;
+ _Py_IDENTIFIER(version);
+
+ if (key == NULL)
+ return -1;
+
+ WarningsState *st = warnings_get_state();
+ if (st == NULL) {
+ return -1;
+ }
+ version_obj = _PyDict_GetItemIdWithError(registry, &PyId_version);
+ if (version_obj == NULL
+ || !PyLong_CheckExact(version_obj)
+ || PyLong_AsLong(version_obj) != st->filters_version)
+ {
+ if (PyErr_Occurred()) {
+ return -1;
+ }
+ PyDict_Clear(registry);
+ version_obj = PyLong_FromLong(st->filters_version);
+ if (version_obj == NULL)
+ return -1;
+ if (_PyDict_SetItemId(registry, &PyId_version, version_obj) < 0) {
+ Py_DECREF(version_obj);
+ return -1;
+ }
+ Py_DECREF(version_obj);
+ }
+ else {
+ already_warned = PyDict_GetItemWithError(registry, key);
+ if (already_warned != NULL) {
+ int rc = PyObject_IsTrue(already_warned);
+ if (rc != 0)
+ return rc;
+ }
+ else if (PyErr_Occurred()) {
+ return -1;
+ }
+ }
+
+ /* This warning wasn't found in the registry, set it. */
+ if (should_set)
+ return PyDict_SetItem(registry, key, Py_True);
+ return 0;
+}
+
+/* New reference. */
+static PyObject *
+normalize_module(PyObject *filename)
+{
+ PyObject *module;
+ int kind;
+ const void *data;
+ Py_ssize_t len;
+
+ len = PyUnicode_GetLength(filename);
+ if (len < 0)
+ return NULL;
+
+ if (len == 0)
+ return PyUnicode_FromString("<unknown>");
+
+ kind = PyUnicode_KIND(filename);
+ data = PyUnicode_DATA(filename);
+
+ /* if filename.endswith(".py"): */
+ if (len >= 3 &&
+ PyUnicode_READ(kind, data, len-3) == '.' &&
+ PyUnicode_READ(kind, data, len-2) == 'p' &&
+ PyUnicode_READ(kind, data, len-1) == 'y')
+ {
+ module = PyUnicode_Substring(filename, 0, len-3);
+ }
+ else {
+ module = filename;
+ Py_INCREF(module);
+ }
+ return module;
+}
+
+static int
+update_registry(PyObject *registry, PyObject *text, PyObject *category,
+ int add_zero)
+{
+ PyObject *altkey;
+ int rc;
+
+ if (add_zero)
+ altkey = PyTuple_Pack(3, text, category, _PyLong_Zero);
+ else
+ altkey = PyTuple_Pack(2, text, category);
+
+ rc = already_warned(registry, altkey, 1);
+ Py_XDECREF(altkey);
+ return rc;
+}
+
+static void
+show_warning(PyObject *filename, int lineno, PyObject *text,
+ PyObject *category, PyObject *sourceline)
+{
+ PyObject *f_stderr;
+ PyObject *name;
+ char lineno_str[128];
+
+ PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
+
+ name = _PyObject_GetAttrId(category, &PyId___name__);
+ if (name == NULL) {
+ goto error;
+ }
+
+ f_stderr = _PySys_GetObjectId(&PyId_stderr);
+ if (f_stderr == NULL) {
+ fprintf(stderr, "lost sys.stderr\n");
+ goto error;
+ }
+
+ /* Print "filename:lineno: category: text\n" */
+ if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0)
+ goto error;
+ if (PyFile_WriteString(lineno_str, f_stderr) < 0)
+ goto error;
+ if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0)
+ goto error;
+ if (PyFile_WriteString(": ", f_stderr) < 0)
+ goto error;
+ if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0)
+ goto error;
+ if (PyFile_WriteString("\n", f_stderr) < 0)
+ goto error;
+ Py_CLEAR(name);
+
+ /* Print " source_line\n" */
+ if (sourceline) {
+ int kind;
+ const void *data;
+ Py_ssize_t i, len;
+ Py_UCS4 ch;
+ PyObject *truncated;
+
+ if (PyUnicode_READY(sourceline) < 1)
+ goto error;
+
+ kind = PyUnicode_KIND(sourceline);
+ data = PyUnicode_DATA(sourceline);
+ len = PyUnicode_GET_LENGTH(sourceline);
+ for (i=0; i<len; i++) {
+ ch = PyUnicode_READ(kind, data, i);
+ if (ch != ' ' && ch != '\t' && ch != '\014')
+ break;
+ }
+
+ truncated = PyUnicode_Substring(sourceline, i, len);
+ if (truncated == NULL)
+ goto error;
+
+ PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW);
+ Py_DECREF(truncated);
+ PyFile_WriteString("\n", f_stderr);
+ }
+ else {
+ _Py_DisplaySourceLine(f_stderr, filename, lineno, 2);
+ }
+
+error:
+ Py_XDECREF(name);
+ PyErr_Clear();
+}
+
+static int
+call_show_warning(PyObject *category, PyObject *text, PyObject *message,
+ PyObject *filename, int lineno, PyObject *lineno_obj,
+ PyObject *sourceline, PyObject *source)
+{
+ PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL;
+ _Py_IDENTIFIER(_showwarnmsg);
+ _Py_IDENTIFIER(WarningMessage);
+
+ /* If the source parameter is set, try to get the Python implementation.
+ The Python implementation is able to log the traceback where the source
+ was allocated, whereas the C implementation doesn't. */
+ show_fn = get_warnings_attr(&PyId__showwarnmsg, source != NULL);
+ if (show_fn == NULL) {
+ if (PyErr_Occurred())
+ return -1;
+ show_warning(filename, lineno, text, category, sourceline);
+ return 0;
+ }
+
+ if (!PyCallable_Check(show_fn)) {
+ PyErr_SetString(PyExc_TypeError,
+ "warnings._showwarnmsg() must be set to a callable");
+ goto error;
+ }
+
+ warnmsg_cls = get_warnings_attr(&PyId_WarningMessage, 0);
+ if (warnmsg_cls == NULL) {
+ if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "unable to get warnings.WarningMessage");
+ }
+ goto error;
+ }
+
+ msg = PyObject_CallFunctionObjArgs(warnmsg_cls, message, category,
+ filename, lineno_obj, Py_None, Py_None, source,
+ NULL);
+ Py_DECREF(warnmsg_cls);
+ if (msg == NULL)
+ goto error;
+
+ res = PyObject_CallOneArg(show_fn, msg);
+ Py_DECREF(show_fn);
+ Py_DECREF(msg);
+
+ if (res == NULL)
+ return -1;
+
+ Py_DECREF(res);
+ return 0;
+
+error:
+ Py_XDECREF(show_fn);
+ return -1;
+}
+
+static PyObject *
+warn_explicit(PyObject *category, PyObject *message,
+ PyObject *filename, int lineno,
+ PyObject *module, PyObject *registry, PyObject *sourceline,
+ PyObject *source)
+{
+ PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
+ PyObject *item = NULL;
+ PyObject *action;
+ int rc;
+
+ /* module can be None if a warning is emitted late during Python shutdown.
+ In this case, the Python warnings module was probably unloaded, filters
+ are no more available to choose as action. It is safer to ignore the
+ warning and do nothing. */
+ if (module == Py_None)
+ Py_RETURN_NONE;
+
+ if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'registry' must be a dict or None");
+ return NULL;
+ }
+
+ /* Normalize module. */
+ if (module == NULL) {
+ module = normalize_module(filename);
+ if (module == NULL)
+ return NULL;
+ }
+ else
+ Py_INCREF(module);
+
+ /* Normalize message. */
+ Py_INCREF(message); /* DECREF'ed in cleanup. */
+ rc = PyObject_IsInstance(message, PyExc_Warning);
+ if (rc == -1) {
+ goto cleanup;
+ }
+ if (rc == 1) {
+ text = PyObject_Str(message);
+ if (text == NULL)
+ goto cleanup;
+ category = (PyObject*)Py_TYPE(message);
+ }
+ else {
+ text = message;
+ message = PyObject_CallOneArg(category, message);
+ if (message == NULL)
+ goto cleanup;
+ }
+
+ lineno_obj = PyLong_FromLong(lineno);
+ if (lineno_obj == NULL)
+ goto cleanup;
+
+ if (source == Py_None) {
+ source = NULL;
+ }
+
+ /* Create key. */
+ key = PyTuple_Pack(3, text, category, lineno_obj);
+ if (key == NULL)
+ goto cleanup;
+
+ if ((registry != NULL) && (registry != Py_None)) {
+ rc = already_warned(registry, key, 0);
+ if (rc == -1)
+ goto cleanup;
+ else if (rc == 1)
+ goto return_none;
+ /* Else this warning hasn't been generated before. */
+ }
+
+ action = get_filter(category, text, lineno, module, &item);
+ if (action == NULL)
+ goto cleanup;
+
+ if (_PyUnicode_EqualToASCIIString(action, "error")) {
+ PyErr_SetObject(category, message);
+ goto cleanup;
+ }
+
+ if (_PyUnicode_EqualToASCIIString(action, "ignore")) {
+ goto return_none;
+ }
+
+ /* Store in the registry that we've been here, *except* when the action
+ is "always". */
+ rc = 0;
+ if (!_PyUnicode_EqualToASCIIString(action, "always")) {
+ if (registry != NULL && registry != Py_None &&
+ PyDict_SetItem(registry, key, Py_True) < 0)
+ {
+ goto cleanup;
+ }
+
+ if (_PyUnicode_EqualToASCIIString(action, "once")) {
+ if (registry == NULL || registry == Py_None) {
+ WarningsState *st = warnings_get_state();
+ if (st == NULL) {
+ goto cleanup;
+ }
+ registry = get_once_registry(st);
+ if (registry == NULL)
+ goto cleanup;
+ }
+ /* WarningsState.once_registry[(text, category)] = 1 */
+ rc = update_registry(registry, text, category, 0);
+ }
+ else if (_PyUnicode_EqualToASCIIString(action, "module")) {
+ /* registry[(text, category, 0)] = 1 */
+ if (registry != NULL && registry != Py_None)
+ rc = update_registry(registry, text, category, 0);
+ }
+ else if (!_PyUnicode_EqualToASCIIString(action, "default")) {
+ PyErr_Format(PyExc_RuntimeError,
+ "Unrecognized action (%R) in warnings.filters:\n %R",
+ action, item);
+ goto cleanup;
+ }
+ }
+
+ if (rc == 1) /* Already warned for this module. */
+ goto return_none;
+ if (rc == 0) {
+ if (call_show_warning(category, text, message, filename, lineno,
+ lineno_obj, sourceline, source) < 0)
+ goto cleanup;
+ }
+ else /* if (rc == -1) */
+ goto cleanup;
+
+ return_none:
+ result = Py_None;
+ Py_INCREF(result);
+
+ cleanup:
+ Py_XDECREF(item);
+ Py_XDECREF(key);
+ Py_XDECREF(text);
+ Py_XDECREF(lineno_obj);
+ Py_DECREF(module);
+ Py_XDECREF(message);
+ return result; /* Py_None or NULL. */
+}
+
+static int
+is_internal_frame(PyFrameObject *frame)
+{
+ static PyObject *importlib_string = NULL;
+ static PyObject *bootstrap_string = NULL;
+ int contains;
+
+ if (importlib_string == NULL) {
+ importlib_string = PyUnicode_FromString("importlib");
+ if (importlib_string == NULL) {
+ return 0;
+ }
+
+ bootstrap_string = PyUnicode_FromString("_bootstrap");
+ if (bootstrap_string == NULL) {
+ Py_DECREF(importlib_string);
+ return 0;
+ }
+ Py_INCREF(importlib_string);
+ Py_INCREF(bootstrap_string);
+ }
+
+ if (frame == NULL) {
+ return 0;
+ }
+
+ PyCodeObject *code = PyFrame_GetCode(frame);
+ PyObject *filename = code->co_filename;
+ Py_DECREF(code);
+
+ if (filename == NULL) {
+ return 0;
+ }
+ if (!PyUnicode_Check(filename)) {
+ return 0;
+ }
+
+ contains = PyUnicode_Contains(filename, importlib_string);
+ if (contains < 0) {
+ return 0;
+ }
+ else if (contains > 0) {
+ contains = PyUnicode_Contains(filename, bootstrap_string);
+ if (contains < 0) {
+ return 0;
+ }
+ else if (contains > 0) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static PyFrameObject *
+next_external_frame(PyFrameObject *frame)
+{
+ do {
+ PyFrameObject *back = PyFrame_GetBack(frame);
+ Py_DECREF(frame);
+ frame = back;
+ } while (frame != NULL && is_internal_frame(frame));
+
+ return frame;
+}
+
+/* filename, module, and registry are new refs, globals is borrowed */
+/* Returns 0 on error (no new refs), 1 on success */
+static int
+setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
+ PyObject **module, PyObject **registry)
+{
+ _Py_IDENTIFIER(__warningregistry__);
+ PyObject *globals;
+
+ /* Setup globals, filename and lineno. */
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyFrameObject *f = PyThreadState_GetFrame(tstate);
+ // Stack level comparisons to Python code is off by one as there is no
+ // warnings-related stack level to avoid.
+ if (stack_level <= 0 || is_internal_frame(f)) {
+ while (--stack_level > 0 && f != NULL) {
+ PyFrameObject *back = PyFrame_GetBack(f);
+ Py_DECREF(f);
+ f = back;
+ }
+ }
+ else {
+ while (--stack_level > 0 && f != NULL) {
+ f = next_external_frame(f);
+ }
+ }
+
+ if (f == NULL) {
+ globals = _PyInterpreterState_GET()->sysdict;
+ *filename = PyUnicode_FromString("sys");
+ *lineno = 1;
+ }
+ else {
+ globals = f->f_globals;
+ PyCodeObject *code = PyFrame_GetCode(f);
+ *filename = code->co_filename;
+ Py_DECREF(code);
+ Py_INCREF(*filename);
+ *lineno = PyFrame_GetLineNumber(f);
+ Py_DECREF(f);
+ }
+
+ *module = NULL;
+
+ /* Setup registry. */
+ assert(globals != NULL);
+ assert(PyDict_Check(globals));
+ *registry = _PyDict_GetItemIdWithError(globals, &PyId___warningregistry__);
+ if (*registry == NULL) {
+ int rc;
+
+ if (_PyErr_Occurred(tstate)) {
+ goto handle_error;
+ }
+ *registry = PyDict_New();
+ if (*registry == NULL)
+ goto handle_error;
+
+ rc = _PyDict_SetItemId(globals, &PyId___warningregistry__, *registry);
+ if (rc < 0)
+ goto handle_error;
+ }
+ else
+ Py_INCREF(*registry);
+
+ /* Setup module. */
+ *module = _PyDict_GetItemIdWithError(globals, &PyId___name__);
+ if (*module == Py_None || (*module != NULL && PyUnicode_Check(*module))) {
+ Py_INCREF(*module);
+ }
+ else if (_PyErr_Occurred(tstate)) {
+ goto handle_error;
+ }
+ else {
+ *module = PyUnicode_FromString("<string>");
+ if (*module == NULL)
+ goto handle_error;
+ }
+
+ return 1;
+
+ handle_error:
+ Py_XDECREF(*registry);
+ Py_XDECREF(*module);
+ Py_DECREF(*filename);
+ return 0;
+}
+
+static PyObject *
+get_category(PyObject *message, PyObject *category)
+{
+ int rc;
+
+ /* Get category. */
+ rc = PyObject_IsInstance(message, PyExc_Warning);
+ if (rc == -1)
+ return NULL;
+
+ if (rc == 1)
+ category = (PyObject*)Py_TYPE(message);
+ else if (category == NULL || category == Py_None)
+ category = PyExc_UserWarning;
+
+ /* Validate category. */
+ rc = PyObject_IsSubclass(category, PyExc_Warning);
+ /* category is not a subclass of PyExc_Warning or
+ PyObject_IsSubclass raised an error */
+ if (rc == -1 || rc == 0) {
+ PyErr_Format(PyExc_TypeError,
+ "category must be a Warning subclass, not '%s'",
+ Py_TYPE(category)->tp_name);
+ return NULL;
+ }
+
+ return category;
+}
+
+static PyObject *
+do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level,
+ PyObject *source)
+{
+ PyObject *filename, *module, *registry, *res;
+ int lineno;
+
+ if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
+ return NULL;
+
+ res = warn_explicit(category, message, filename, lineno, module, registry,
+ NULL, source);
+ Py_DECREF(filename);
+ Py_DECREF(registry);
+ Py_DECREF(module);
+ return res;
+}
+
+/*[clinic input]
+warn as warnings_warn
+
+ message: object
+ category: object = None
+ stacklevel: Py_ssize_t = 1
+ source: object = None
+
+Issue a warning, or maybe ignore it or raise an exception.
+[clinic start generated code]*/
+
+static PyObject *
+warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category,
+ Py_ssize_t stacklevel, PyObject *source)
+/*[clinic end generated code: output=31ed5ab7d8d760b2 input=bfdf5cf99f6c4edd]*/
+{
+ category = get_category(message, category);
+ if (category == NULL)
+ return NULL;
+ return do_warn(message, category, stacklevel, source);
+}
+
+static PyObject *
+get_source_line(PyObject *module_globals, int lineno)
+{
+ _Py_IDENTIFIER(get_source);
+ _Py_IDENTIFIER(__loader__);
+ PyObject *loader;
+ PyObject *module_name;
+ PyObject *get_source;
+ PyObject *source;
+ PyObject *source_list;
+ PyObject *source_line;
+
+ /* Check/get the requisite pieces needed for the loader. */
+ loader = _PyDict_GetItemIdWithError(module_globals, &PyId___loader__);
+ if (loader == NULL) {
+ return NULL;
+ }
+ Py_INCREF(loader);
+ module_name = _PyDict_GetItemIdWithError(module_globals, &PyId___name__);
+ if (!module_name) {
+ Py_DECREF(loader);
+ return NULL;
+ }
+ Py_INCREF(module_name);
+
+ /* Make sure the loader implements the optional get_source() method. */
+ (void)_PyObject_LookupAttrId(loader, &PyId_get_source, &get_source);
+ Py_DECREF(loader);
+ if (!get_source) {
+ Py_DECREF(module_name);
+ return NULL;
+ }
+ /* Call get_source() to get the source code. */
+ source = PyObject_CallOneArg(get_source, module_name);
+ Py_DECREF(get_source);
+ Py_DECREF(module_name);
+ if (!source) {
+ return NULL;
+ }
+ if (source == Py_None) {
+ Py_DECREF(source);
+ return NULL;
+ }
+
+ /* Split the source into lines. */
+ source_list = PyUnicode_Splitlines(source, 0);
+ Py_DECREF(source);
+ if (!source_list) {
+ return NULL;
+ }
+
+ /* Get the source line. */
+ source_line = PyList_GetItem(source_list, lineno-1);
+ Py_XINCREF(source_line);
+ Py_DECREF(source_list);
+ return source_line;
+}
+
+static PyObject *
+warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwd_list[] = {"message", "category", "filename", "lineno",
+ "module", "registry", "module_globals",
+ "source", 0};
+ PyObject *message;
+ PyObject *category;
+ PyObject *filename;
+ int lineno;
+ PyObject *module = NULL;
+ PyObject *registry = NULL;
+ PyObject *module_globals = NULL;
+ PyObject *sourceobj = NULL;
+ PyObject *source_line = NULL;
+ PyObject *returned;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOOO:warn_explicit",
+ kwd_list, &message, &category, &filename, &lineno, &module,
+ &registry, &module_globals, &sourceobj))
+ return NULL;
+
+ if (module_globals && module_globals != Py_None) {
+ if (!PyDict_Check(module_globals)) {
+ PyErr_Format(PyExc_TypeError,
+ "module_globals must be a dict, not '%.200s'",
+ Py_TYPE(module_globals)->tp_name);
+ return NULL;
+ }
+
+ source_line = get_source_line(module_globals, lineno);
+ if (source_line == NULL && PyErr_Occurred()) {
+ return NULL;
+ }
+ }
+ returned = warn_explicit(category, message, filename, lineno, module,
+ registry, source_line, sourceobj);
+ Py_XDECREF(source_line);
+ return returned;
+}
+
+static PyObject *
+warnings_filters_mutated(PyObject *self, PyObject *args)
+{
+ WarningsState *st = warnings_get_state();
+ if (st == NULL) {
+ return NULL;
+ }
+ st->filters_version++;
+ Py_RETURN_NONE;
+}
+
+
+/* Function to issue a warning message; may raise an exception. */
+
+static int
+warn_unicode(PyObject *category, PyObject *message,
+ Py_ssize_t stack_level, PyObject *source)
+{
+ PyObject *res;
+
+ if (category == NULL)
+ category = PyExc_RuntimeWarning;
+
+ res = do_warn(message, category, stack_level, source);
+ if (res == NULL)
+ return -1;
+ Py_DECREF(res);
+
+ return 0;
+}
+
+static int
+_PyErr_WarnFormatV(PyObject *source,
+ PyObject *category, Py_ssize_t stack_level,
+ const char *format, va_list vargs)
+{
+ PyObject *message;
+ int res;
+
+ message = PyUnicode_FromFormatV(format, vargs);
+ if (message == NULL)
+ return -1;
+
+ res = warn_unicode(category, message, stack_level, source);
+ Py_DECREF(message);
+ return res;
+}
+
+int
+PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
+ const char *format, ...)
+{
+ int res;
+ va_list vargs;
+
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, format);
+#else
+ va_start(vargs);
+#endif
+ res = _PyErr_WarnFormatV(NULL, category, stack_level, format, vargs);
+ va_end(vargs);
+ return res;
+}
+
+static int
+_PyErr_WarnFormat(PyObject *source, PyObject *category, Py_ssize_t stack_level,
+ const char *format, ...)
+{
+ int res;
+ va_list vargs;
+
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, format);
+#else
+ va_start(vargs);
+#endif
+ res = _PyErr_WarnFormatV(source, category, stack_level, format, vargs);
+ va_end(vargs);
+ return res;
+}
+
+int
+PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level,
+ const char *format, ...)
+{
+ int res;
+ va_list vargs;
+
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, format);
+#else
+ va_start(vargs);
+#endif
+ res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning,
+ stack_level, format, vargs);
+ va_end(vargs);
+ return res;
+}
+
+
+int
+PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
+{
+ int ret;
+ PyObject *message = PyUnicode_FromString(text);
+ if (message == NULL)
+ return -1;
+ ret = warn_unicode(category, message, stack_level, NULL);
+ Py_DECREF(message);
+ return ret;
+}
+
+/* PyErr_Warn is only for backwards compatibility and will be removed.
+ Use PyErr_WarnEx instead. */
+
+#undef PyErr_Warn
+
+int
+PyErr_Warn(PyObject *category, const char *text)
+{
+ return PyErr_WarnEx(category, text, 1);
+}
+
+/* Warning with explicit origin */
+int
+PyErr_WarnExplicitObject(PyObject *category, PyObject *message,
+ PyObject *filename, int lineno,
+ PyObject *module, PyObject *registry)
+{
+ PyObject *res;
+ if (category == NULL)
+ category = PyExc_RuntimeWarning;
+ res = warn_explicit(category, message, filename, lineno,
+ module, registry, NULL, NULL);
+ if (res == NULL)
+ return -1;
+ Py_DECREF(res);
+ return 0;
+}
+
+int
+PyErr_WarnExplicit(PyObject *category, const char *text,
+ const char *filename_str, int lineno,
+ const char *module_str, PyObject *registry)
+{
+ PyObject *message = PyUnicode_FromString(text);
+ PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
+ PyObject *module = NULL;
+ int ret = -1;
+
+ if (message == NULL || filename == NULL)
+ goto exit;
+ if (module_str != NULL) {
+ module = PyUnicode_FromString(module_str);
+ if (module == NULL)
+ goto exit;
+ }
+
+ ret = PyErr_WarnExplicitObject(category, message, filename, lineno,
+ module, registry);
+
+ exit:
+ Py_XDECREF(message);
+ Py_XDECREF(module);
+ Py_XDECREF(filename);
+ return ret;
+}
+
+int
+PyErr_WarnExplicitFormat(PyObject *category,
+ const char *filename_str, int lineno,
+ const char *module_str, PyObject *registry,
+ const char *format, ...)
+{
+ PyObject *message;
+ PyObject *module = NULL;
+ PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
+ int ret = -1;
+ va_list vargs;
+
+ if (filename == NULL)
+ goto exit;
+ if (module_str != NULL) {
+ module = PyUnicode_FromString(module_str);
+ if (module == NULL)
+ goto exit;
+ }
+
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, format);
+#else
+ va_start(vargs);
+#endif
+ message = PyUnicode_FromFormatV(format, vargs);
+ if (message != NULL) {
+ PyObject *res;
+ res = warn_explicit(category, message, filename, lineno,
+ module, registry, NULL, NULL);
+ Py_DECREF(message);
+ if (res != NULL) {
+ Py_DECREF(res);
+ ret = 0;
+ }
+ }
+ va_end(vargs);
+exit:
+ Py_XDECREF(module);
+ Py_XDECREF(filename);
+ return ret;
+}
+
+void
+_PyErr_WarnUnawaitedCoroutine(PyObject *coro)
+{
+ /* First, we attempt to funnel the warning through
+ warnings._warn_unawaited_coroutine.
+
+ This could raise an exception, due to:
+ - a bug
+ - some kind of shutdown-related brokenness
+ - succeeding, but with an "error" warning filter installed, so the
+ warning is converted into a RuntimeWarning exception
+
+ In the first two cases, we want to print the error (so we know what it
+ is!), and then print a warning directly as a fallback. In the last
+ case, we want to print the error (since it's the warning!), but *not*
+ do a fallback. And after we print the error we can't check for what
+ type of error it was (because PyErr_WriteUnraisable clears it), so we
+ need a flag to keep track.
+
+ Since this is called from __del__ context, it's careful to never raise
+ an exception.
+ */
+ _Py_IDENTIFIER(_warn_unawaited_coroutine);
+ int warned = 0;
+ PyObject *fn = get_warnings_attr(&PyId__warn_unawaited_coroutine, 1);
+ if (fn) {
+ PyObject *res = PyObject_CallOneArg(fn, coro);
+ Py_DECREF(fn);
+ if (res || PyErr_ExceptionMatches(PyExc_RuntimeWarning)) {
+ warned = 1;
+ }
+ Py_XDECREF(res);
+ }
+
+ if (PyErr_Occurred()) {
+ PyErr_WriteUnraisable(coro);
+ }
+ if (!warned) {
+ if (_PyErr_WarnFormat(coro, PyExc_RuntimeWarning, 1,
+ "coroutine '%S' was never awaited",
+ ((PyCoroObject *)coro)->cr_qualname) < 0)
+ {
+ PyErr_WriteUnraisable(coro);
+ }
+ }
+}
+
+PyDoc_STRVAR(warn_explicit_doc,
+"Low-level interface to warnings functionality.");
+
+static PyMethodDef warnings_functions[] = {
+ WARNINGS_WARN_METHODDEF
+ {"warn_explicit", (PyCFunction)(void(*)(void))warnings_warn_explicit,
+ METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
+ {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS,
+ NULL},
+ /* XXX(brett.cannon): add showwarning? */
+ /* XXX(brett.cannon): Reasonable to add formatwarning? */
+ {NULL, NULL} /* sentinel */
+};
+
+
+static struct PyModuleDef warningsmodule = {
+ PyModuleDef_HEAD_INIT,
+ MODULE_NAME, /* m_name */
+ warnings__doc__, /* m_doc */
+ 0, /* m_size */
+ warnings_functions, /* m_methods */
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL /* m_free */
+};
+
+
+PyStatus
+_PyWarnings_InitState(PyThreadState *tstate)
+{
+ if (warnings_init_state(&tstate->interp->warnings) < 0) {
+ return _PyStatus_ERR("can't initialize warnings");
+ }
+ return _PyStatus_OK();
+}
+
+
+PyMODINIT_FUNC
+_PyWarnings_Init(void)
+{
+ PyObject *m;
+
+ m = PyModule_Create(&warningsmodule);
+ if (m == NULL) {
+ return NULL;
+ }
+
+ WarningsState *st = warnings_get_state();
+ if (st == NULL) {
+ goto error;
+ }
+ if (warnings_init_state(st) < 0) {
+ goto error;
+ }
+
+ Py_INCREF(st->filters);
+ if (PyModule_AddObject(m, "filters", st->filters) < 0) {
+ goto error;
+ }
+
+ Py_INCREF(st->once_registry);
+ if (PyModule_AddObject(m, "_onceregistry", st->once_registry) < 0) {
+ goto error;
+ }
+
+ Py_INCREF(st->default_action);
+ if (PyModule_AddObject(m, "_defaultaction", st->default_action) < 0) {
+ goto error;
+ }
+
+ return m;
+
+error:
+ if (st != NULL) {
+ warnings_clear_state(st);
+ }
+ Py_DECREF(m);
+ return NULL;
+}
+
+// We need this to ensure that warnings still work until late in finalization.
+void
+_PyWarnings_Fini(PyInterpreterState *interp)
+{
+ warnings_clear_state(&interp->warnings);
+}
diff --git a/contrib/tools/python3/src/Python/asdl.c b/contrib/tools/python3/src/Python/asdl.c
new file mode 100644
index 00000000000..c2110781181
--- /dev/null
+++ b/contrib/tools/python3/src/Python/asdl.c
@@ -0,0 +1,64 @@
+#include "Python.h"
+#include "asdl.h"
+
+asdl_seq *
+_Py_asdl_seq_new(Py_ssize_t size, PyArena *arena)
+{
+ asdl_seq *seq = NULL;
+ size_t n;
+
+ /* check size is sane */
+ if (size < 0 ||
+ (size && (((size_t)size - 1) > (SIZE_MAX / sizeof(void *))))) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ n = (size ? (sizeof(void *) * (size - 1)) : 0);
+
+ /* check if size can be added safely */
+ if (n > SIZE_MAX - sizeof(asdl_seq)) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ n += sizeof(asdl_seq);
+
+ seq = (asdl_seq *)PyArena_Malloc(arena, n);
+ if (!seq) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ memset(seq, 0, n);
+ seq->size = size;
+ return seq;
+}
+
+asdl_int_seq *
+_Py_asdl_int_seq_new(Py_ssize_t size, PyArena *arena)
+{
+ asdl_int_seq *seq = NULL;
+ size_t n;
+
+ /* check size is sane */
+ if (size < 0 ||
+ (size && (((size_t)size - 1) > (SIZE_MAX / sizeof(void *))))) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ n = (size ? (sizeof(void *) * (size - 1)) : 0);
+
+ /* check if size can be added safely */
+ if (n > SIZE_MAX - sizeof(asdl_seq)) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ n += sizeof(asdl_seq);
+
+ seq = (asdl_int_seq *)PyArena_Malloc(arena, n);
+ if (!seq) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ memset(seq, 0, n);
+ seq->size = size;
+ return seq;
+}
diff --git a/contrib/tools/python3/src/Python/ast.c b/contrib/tools/python3/src/Python/ast.c
new file mode 100644
index 00000000000..6dd70592631
--- /dev/null
+++ b/contrib/tools/python3/src/Python/ast.c
@@ -0,0 +1,5858 @@
+/*
+ * This file includes functions to transform a concrete syntax tree (CST) to
+ * an abstract syntax tree (AST). The main function is PyAST_FromNode().
+ *
+ */
+#include "Python.h"
+#include "Python-ast.h"
+#include "node.h"
+#include "ast.h"
+#include "token.h"
+#include "pythonrun.h"
+
+#include <assert.h>
+#include <stdbool.h>
+
+#define MAXLEVEL 200 /* Max parentheses level */
+
+static int validate_stmts(asdl_seq *);
+static int validate_exprs(asdl_seq *, expr_context_ty, int);
+static int validate_nonempty_seq(asdl_seq *, const char *, const char *);
+static int validate_stmt(stmt_ty);
+static int validate_expr(expr_ty, expr_context_ty);
+
+static int
+validate_name(PyObject *name)
+{
+ assert(PyUnicode_Check(name));
+ static const char * const forbidden[] = {
+ "None",
+ "True",
+ "False",
+ NULL
+ };
+ for (int i = 0; forbidden[i] != NULL; i++) {
+ if (_PyUnicode_EqualToASCIIString(name, forbidden[i])) {
+ PyErr_Format(PyExc_ValueError, "Name node can't be used with '%s' constant", forbidden[i]);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int
+validate_comprehension(asdl_seq *gens)
+{
+ Py_ssize_t i;
+ if (!asdl_seq_LEN(gens)) {
+ PyErr_SetString(PyExc_ValueError, "comprehension with no generators");
+ return 0;
+ }
+ for (i = 0; i < asdl_seq_LEN(gens); i++) {
+ comprehension_ty comp = asdl_seq_GET(gens, i);
+ if (!validate_expr(comp->target, Store) ||
+ !validate_expr(comp->iter, Load) ||
+ !validate_exprs(comp->ifs, Load, 0))
+ return 0;
+ }
+ return 1;
+}
+
+static int
+validate_keywords(asdl_seq *keywords)
+{
+ Py_ssize_t i;
+ for (i = 0; i < asdl_seq_LEN(keywords); i++)
+ if (!validate_expr(((keyword_ty)asdl_seq_GET(keywords, i))->value, Load))
+ return 0;
+ return 1;
+}
+
+static int
+validate_args(asdl_seq *args)
+{
+ Py_ssize_t i;
+ for (i = 0; i < asdl_seq_LEN(args); i++) {
+ arg_ty arg = asdl_seq_GET(args, i);
+ if (arg->annotation && !validate_expr(arg->annotation, Load))
+ return 0;
+ }
+ return 1;
+}
+
+static const char *
+expr_context_name(expr_context_ty ctx)
+{
+ switch (ctx) {
+ case Load:
+ return "Load";
+ case Store:
+ return "Store";
+ case Del:
+ return "Del";
+ default:
+ Py_UNREACHABLE();
+ }
+}
+
+static int
+validate_arguments(arguments_ty args)
+{
+ if (!validate_args(args->posonlyargs) || !validate_args(args->args)) {
+ return 0;
+ }
+ if (args->vararg && args->vararg->annotation
+ && !validate_expr(args->vararg->annotation, Load)) {
+ return 0;
+ }
+ if (!validate_args(args->kwonlyargs))
+ return 0;
+ if (args->kwarg && args->kwarg->annotation
+ && !validate_expr(args->kwarg->annotation, Load)) {
+ return 0;
+ }
+ if (asdl_seq_LEN(args->defaults) > asdl_seq_LEN(args->posonlyargs) + asdl_seq_LEN(args->args)) {
+ PyErr_SetString(PyExc_ValueError, "more positional defaults than args on arguments");
+ return 0;
+ }
+ if (asdl_seq_LEN(args->kw_defaults) != asdl_seq_LEN(args->kwonlyargs)) {
+ PyErr_SetString(PyExc_ValueError, "length of kwonlyargs is not the same as "
+ "kw_defaults on arguments");
+ return 0;
+ }
+ return validate_exprs(args->defaults, Load, 0) && validate_exprs(args->kw_defaults, Load, 1);
+}
+
+static int
+validate_constant(PyObject *value)
+{
+ if (value == Py_None || value == Py_Ellipsis)
+ return 1;
+
+ if (PyLong_CheckExact(value)
+ || PyFloat_CheckExact(value)
+ || PyComplex_CheckExact(value)
+ || PyBool_Check(value)
+ || PyUnicode_CheckExact(value)
+ || PyBytes_CheckExact(value))
+ return 1;
+
+ if (PyTuple_CheckExact(value) || PyFrozenSet_CheckExact(value)) {
+ PyObject *it;
+
+ it = PyObject_GetIter(value);
+ if (it == NULL)
+ return 0;
+
+ while (1) {
+ PyObject *item = PyIter_Next(it);
+ if (item == NULL) {
+ if (PyErr_Occurred()) {
+ Py_DECREF(it);
+ return 0;
+ }
+ break;
+ }
+
+ if (!validate_constant(item)) {
+ Py_DECREF(it);
+ Py_DECREF(item);
+ return 0;
+ }
+ Py_DECREF(item);
+ }
+
+ Py_DECREF(it);
+ return 1;
+ }
+
+ if (!PyErr_Occurred()) {
+ PyErr_Format(PyExc_TypeError,
+ "got an invalid type in Constant: %s",
+ _PyType_Name(Py_TYPE(value)));
+ }
+ return 0;
+}
+
+static int
+validate_expr(expr_ty exp, expr_context_ty ctx)
+{
+ int check_ctx = 1;
+ expr_context_ty actual_ctx;
+
+ /* First check expression context. */
+ switch (exp->kind) {
+ case Attribute_kind:
+ actual_ctx = exp->v.Attribute.ctx;
+ break;
+ case Subscript_kind:
+ actual_ctx = exp->v.Subscript.ctx;
+ break;
+ case Starred_kind:
+ actual_ctx = exp->v.Starred.ctx;
+ break;
+ case Name_kind:
+ if (!validate_name(exp->v.Name.id)) {
+ return 0;
+ }
+ actual_ctx = exp->v.Name.ctx;
+ break;
+ case List_kind:
+ actual_ctx = exp->v.List.ctx;
+ break;
+ case Tuple_kind:
+ actual_ctx = exp->v.Tuple.ctx;
+ break;
+ default:
+ if (ctx != Load) {
+ PyErr_Format(PyExc_ValueError, "expression which can't be "
+ "assigned to in %s context", expr_context_name(ctx));
+ return 0;
+ }
+ check_ctx = 0;
+ /* set actual_ctx to prevent gcc warning */
+ actual_ctx = 0;
+ }
+ if (check_ctx && actual_ctx != ctx) {
+ PyErr_Format(PyExc_ValueError, "expression must have %s context but has %s instead",
+ expr_context_name(ctx), expr_context_name(actual_ctx));
+ return 0;
+ }
+
+ /* Now validate expression. */
+ switch (exp->kind) {
+ case BoolOp_kind:
+ if (asdl_seq_LEN(exp->v.BoolOp.values) < 2) {
+ PyErr_SetString(PyExc_ValueError, "BoolOp with less than 2 values");
+ return 0;
+ }
+ return validate_exprs(exp->v.BoolOp.values, Load, 0);
+ case BinOp_kind:
+ return validate_expr(exp->v.BinOp.left, Load) &&
+ validate_expr(exp->v.BinOp.right, Load);
+ case UnaryOp_kind:
+ return validate_expr(exp->v.UnaryOp.operand, Load);
+ case Lambda_kind:
+ return validate_arguments(exp->v.Lambda.args) &&
+ validate_expr(exp->v.Lambda.body, Load);
+ case IfExp_kind:
+ return validate_expr(exp->v.IfExp.test, Load) &&
+ validate_expr(exp->v.IfExp.body, Load) &&
+ validate_expr(exp->v.IfExp.orelse, Load);
+ case Dict_kind:
+ if (asdl_seq_LEN(exp->v.Dict.keys) != asdl_seq_LEN(exp->v.Dict.values)) {
+ PyErr_SetString(PyExc_ValueError,
+ "Dict doesn't have the same number of keys as values");
+ return 0;
+ }
+ /* null_ok=1 for keys expressions to allow dict unpacking to work in
+ dict literals, i.e. ``{**{a:b}}`` */
+ return validate_exprs(exp->v.Dict.keys, Load, /*null_ok=*/ 1) &&
+ validate_exprs(exp->v.Dict.values, Load, /*null_ok=*/ 0);
+ case Set_kind:
+ return validate_exprs(exp->v.Set.elts, Load, 0);
+#define COMP(NAME) \
+ case NAME ## _kind: \
+ return validate_comprehension(exp->v.NAME.generators) && \
+ validate_expr(exp->v.NAME.elt, Load);
+ COMP(ListComp)
+ COMP(SetComp)
+ COMP(GeneratorExp)
+#undef COMP
+ case DictComp_kind:
+ return validate_comprehension(exp->v.DictComp.generators) &&
+ validate_expr(exp->v.DictComp.key, Load) &&
+ validate_expr(exp->v.DictComp.value, Load);
+ case Yield_kind:
+ return !exp->v.Yield.value || validate_expr(exp->v.Yield.value, Load);
+ case YieldFrom_kind:
+ return validate_expr(exp->v.YieldFrom.value, Load);
+ case Await_kind:
+ return validate_expr(exp->v.Await.value, Load);
+ case Compare_kind:
+ if (!asdl_seq_LEN(exp->v.Compare.comparators)) {
+ PyErr_SetString(PyExc_ValueError, "Compare with no comparators");
+ return 0;
+ }
+ if (asdl_seq_LEN(exp->v.Compare.comparators) !=
+ asdl_seq_LEN(exp->v.Compare.ops)) {
+ PyErr_SetString(PyExc_ValueError, "Compare has a different number "
+ "of comparators and operands");
+ return 0;
+ }
+ return validate_exprs(exp->v.Compare.comparators, Load, 0) &&
+ validate_expr(exp->v.Compare.left, Load);
+ case Call_kind:
+ return validate_expr(exp->v.Call.func, Load) &&
+ validate_exprs(exp->v.Call.args, Load, 0) &&
+ validate_keywords(exp->v.Call.keywords);
+ case Constant_kind:
+ if (!validate_constant(exp->v.Constant.value)) {
+ return 0;
+ }
+ return 1;
+ case JoinedStr_kind:
+ return validate_exprs(exp->v.JoinedStr.values, Load, 0);
+ case FormattedValue_kind:
+ if (validate_expr(exp->v.FormattedValue.value, Load) == 0)
+ return 0;
+ if (exp->v.FormattedValue.format_spec)
+ return validate_expr(exp->v.FormattedValue.format_spec, Load);
+ return 1;
+ case Attribute_kind:
+ return validate_expr(exp->v.Attribute.value, Load);
+ case Subscript_kind:
+ return validate_expr(exp->v.Subscript.slice, Load) &&
+ validate_expr(exp->v.Subscript.value, Load);
+ case Starred_kind:
+ return validate_expr(exp->v.Starred.value, ctx);
+ case Slice_kind:
+ return (!exp->v.Slice.lower || validate_expr(exp->v.Slice.lower, Load)) &&
+ (!exp->v.Slice.upper || validate_expr(exp->v.Slice.upper, Load)) &&
+ (!exp->v.Slice.step || validate_expr(exp->v.Slice.step, Load));
+ case List_kind:
+ return validate_exprs(exp->v.List.elts, ctx, 0);
+ case Tuple_kind:
+ return validate_exprs(exp->v.Tuple.elts, ctx, 0);
+ case NamedExpr_kind:
+ return validate_expr(exp->v.NamedExpr.value, Load);
+ /* This last case doesn't have any checking. */
+ case Name_kind:
+ return 1;
+ }
+ PyErr_SetString(PyExc_SystemError, "unexpected expression");
+ return 0;
+}
+
+static int
+validate_nonempty_seq(asdl_seq *seq, const char *what, const char *owner)
+{
+ if (asdl_seq_LEN(seq))
+ return 1;
+ PyErr_Format(PyExc_ValueError, "empty %s on %s", what, owner);
+ return 0;
+}
+
+static int
+validate_assignlist(asdl_seq *targets, expr_context_ty ctx)
+{
+ return validate_nonempty_seq(targets, "targets", ctx == Del ? "Delete" : "Assign") &&
+ validate_exprs(targets, ctx, 0);
+}
+
+static int
+validate_body(asdl_seq *body, const char *owner)
+{
+ return validate_nonempty_seq(body, "body", owner) && validate_stmts(body);
+}
+
+static int
+validate_stmt(stmt_ty stmt)
+{
+ Py_ssize_t i;
+ switch (stmt->kind) {
+ case FunctionDef_kind:
+ return validate_body(stmt->v.FunctionDef.body, "FunctionDef") &&
+ validate_arguments(stmt->v.FunctionDef.args) &&
+ validate_exprs(stmt->v.FunctionDef.decorator_list, Load, 0) &&
+ (!stmt->v.FunctionDef.returns ||
+ validate_expr(stmt->v.FunctionDef.returns, Load));
+ case ClassDef_kind:
+ return validate_body(stmt->v.ClassDef.body, "ClassDef") &&
+ validate_exprs(stmt->v.ClassDef.bases, Load, 0) &&
+ validate_keywords(stmt->v.ClassDef.keywords) &&
+ validate_exprs(stmt->v.ClassDef.decorator_list, Load, 0);
+ case Return_kind:
+ return !stmt->v.Return.value || validate_expr(stmt->v.Return.value, Load);
+ case Delete_kind:
+ return validate_assignlist(stmt->v.Delete.targets, Del);
+ case Assign_kind:
+ return validate_assignlist(stmt->v.Assign.targets, Store) &&
+ validate_expr(stmt->v.Assign.value, Load);
+ case AugAssign_kind:
+ return validate_expr(stmt->v.AugAssign.target, Store) &&
+ validate_expr(stmt->v.AugAssign.value, Load);
+ case AnnAssign_kind:
+ if (stmt->v.AnnAssign.target->kind != Name_kind &&
+ stmt->v.AnnAssign.simple) {
+ PyErr_SetString(PyExc_TypeError,
+ "AnnAssign with simple non-Name target");
+ return 0;
+ }
+ return validate_expr(stmt->v.AnnAssign.target, Store) &&
+ (!stmt->v.AnnAssign.value ||
+ validate_expr(stmt->v.AnnAssign.value, Load)) &&
+ validate_expr(stmt->v.AnnAssign.annotation, Load);
+ case For_kind:
+ return validate_expr(stmt->v.For.target, Store) &&
+ validate_expr(stmt->v.For.iter, Load) &&
+ validate_body(stmt->v.For.body, "For") &&
+ validate_stmts(stmt->v.For.orelse);
+ case AsyncFor_kind:
+ return validate_expr(stmt->v.AsyncFor.target, Store) &&
+ validate_expr(stmt->v.AsyncFor.iter, Load) &&
+ validate_body(stmt->v.AsyncFor.body, "AsyncFor") &&
+ validate_stmts(stmt->v.AsyncFor.orelse);
+ case While_kind:
+ return validate_expr(stmt->v.While.test, Load) &&
+ validate_body(stmt->v.While.body, "While") &&
+ validate_stmts(stmt->v.While.orelse);
+ case If_kind:
+ return validate_expr(stmt->v.If.test, Load) &&
+ validate_body(stmt->v.If.body, "If") &&
+ validate_stmts(stmt->v.If.orelse);
+ case With_kind:
+ if (!validate_nonempty_seq(stmt->v.With.items, "items", "With"))
+ return 0;
+ for (i = 0; i < asdl_seq_LEN(stmt->v.With.items); i++) {
+ withitem_ty item = asdl_seq_GET(stmt->v.With.items, i);
+ if (!validate_expr(item->context_expr, Load) ||
+ (item->optional_vars && !validate_expr(item->optional_vars, Store)))
+ return 0;
+ }
+ return validate_body(stmt->v.With.body, "With");
+ case AsyncWith_kind:
+ if (!validate_nonempty_seq(stmt->v.AsyncWith.items, "items", "AsyncWith"))
+ return 0;
+ for (i = 0; i < asdl_seq_LEN(stmt->v.AsyncWith.items); i++) {
+ withitem_ty item = asdl_seq_GET(stmt->v.AsyncWith.items, i);
+ if (!validate_expr(item->context_expr, Load) ||
+ (item->optional_vars && !validate_expr(item->optional_vars, Store)))
+ return 0;
+ }
+ return validate_body(stmt->v.AsyncWith.body, "AsyncWith");
+ case Raise_kind:
+ if (stmt->v.Raise.exc) {
+ return validate_expr(stmt->v.Raise.exc, Load) &&
+ (!stmt->v.Raise.cause || validate_expr(stmt->v.Raise.cause, Load));
+ }
+ if (stmt->v.Raise.cause) {
+ PyErr_SetString(PyExc_ValueError, "Raise with cause but no exception");
+ return 0;
+ }
+ return 1;
+ case Try_kind:
+ if (!validate_body(stmt->v.Try.body, "Try"))
+ return 0;
+ if (!asdl_seq_LEN(stmt->v.Try.handlers) &&
+ !asdl_seq_LEN(stmt->v.Try.finalbody)) {
+ PyErr_SetString(PyExc_ValueError, "Try has neither except handlers nor finalbody");
+ return 0;
+ }
+ if (!asdl_seq_LEN(stmt->v.Try.handlers) &&
+ asdl_seq_LEN(stmt->v.Try.orelse)) {
+ PyErr_SetString(PyExc_ValueError, "Try has orelse but no except handlers");
+ return 0;
+ }
+ for (i = 0; i < asdl_seq_LEN(stmt->v.Try.handlers); i++) {
+ excepthandler_ty handler = asdl_seq_GET(stmt->v.Try.handlers, i);
+ if ((handler->v.ExceptHandler.type &&
+ !validate_expr(handler->v.ExceptHandler.type, Load)) ||
+ !validate_body(handler->v.ExceptHandler.body, "ExceptHandler"))
+ return 0;
+ }
+ return (!asdl_seq_LEN(stmt->v.Try.finalbody) ||
+ validate_stmts(stmt->v.Try.finalbody)) &&
+ (!asdl_seq_LEN(stmt->v.Try.orelse) ||
+ validate_stmts(stmt->v.Try.orelse));
+ case Assert_kind:
+ return validate_expr(stmt->v.Assert.test, Load) &&
+ (!stmt->v.Assert.msg || validate_expr(stmt->v.Assert.msg, Load));
+ case Import_kind:
+ return validate_nonempty_seq(stmt->v.Import.names, "names", "Import");
+ case ImportFrom_kind:
+ if (stmt->v.ImportFrom.level < 0) {
+ PyErr_SetString(PyExc_ValueError, "Negative ImportFrom level");
+ return 0;
+ }
+ return validate_nonempty_seq(stmt->v.ImportFrom.names, "names", "ImportFrom");
+ case Global_kind:
+ return validate_nonempty_seq(stmt->v.Global.names, "names", "Global");
+ case Nonlocal_kind:
+ return validate_nonempty_seq(stmt->v.Nonlocal.names, "names", "Nonlocal");
+ case Expr_kind:
+ return validate_expr(stmt->v.Expr.value, Load);
+ case AsyncFunctionDef_kind:
+ return validate_body(stmt->v.AsyncFunctionDef.body, "AsyncFunctionDef") &&
+ validate_arguments(stmt->v.AsyncFunctionDef.args) &&
+ validate_exprs(stmt->v.AsyncFunctionDef.decorator_list, Load, 0) &&
+ (!stmt->v.AsyncFunctionDef.returns ||
+ validate_expr(stmt->v.AsyncFunctionDef.returns, Load));
+ case Pass_kind:
+ case Break_kind:
+ case Continue_kind:
+ return 1;
+ default:
+ PyErr_SetString(PyExc_SystemError, "unexpected statement");
+ return 0;
+ }
+}
+
+static int
+validate_stmts(asdl_seq *seq)
+{
+ Py_ssize_t i;
+ for (i = 0; i < asdl_seq_LEN(seq); i++) {
+ stmt_ty stmt = asdl_seq_GET(seq, i);
+ if (stmt) {
+ if (!validate_stmt(stmt))
+ return 0;
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "None disallowed in statement list");
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int
+validate_exprs(asdl_seq *exprs, expr_context_ty ctx, int null_ok)
+{
+ Py_ssize_t i;
+ for (i = 0; i < asdl_seq_LEN(exprs); i++) {
+ expr_ty expr = asdl_seq_GET(exprs, i);
+ if (expr) {
+ if (!validate_expr(expr, ctx))
+ return 0;
+ }
+ else if (!null_ok) {
+ PyErr_SetString(PyExc_ValueError,
+ "None disallowed in expression list");
+ return 0;
+ }
+
+ }
+ return 1;
+}
+
+int
+PyAST_Validate(mod_ty mod)
+{
+ int res = 0;
+
+ switch (mod->kind) {
+ case Module_kind:
+ res = validate_stmts(mod->v.Module.body);
+ break;
+ case Interactive_kind:
+ res = validate_stmts(mod->v.Interactive.body);
+ break;
+ case Expression_kind:
+ res = validate_expr(mod->v.Expression.body, Load);
+ break;
+ default:
+ PyErr_SetString(PyExc_SystemError, "impossible module node");
+ res = 0;
+ break;
+ }
+ return res;
+}
+
+/* This is done here, so defines like "test" don't interfere with AST use above. */
+#include "grammar.h"
+#include "parsetok.h"
+#include "graminit.h"
+
+/* Data structure used internally */
+struct compiling {
+ PyArena *c_arena; /* Arena for allocating memory. */
+ PyObject *c_filename; /* filename */
+ PyObject *c_normalize; /* Normalization function from unicodedata. */
+ int c_feature_version; /* Latest minor version of Python for allowed features */
+};
+
+static asdl_seq *seq_for_testlist(struct compiling *, const node *);
+static expr_ty ast_for_expr(struct compiling *, const node *);
+static stmt_ty ast_for_stmt(struct compiling *, const node *);
+static asdl_seq *ast_for_suite(struct compiling *c, const node *n);
+static asdl_seq *ast_for_exprlist(struct compiling *, const node *,
+ expr_context_ty);
+static expr_ty ast_for_testlist(struct compiling *, const node *);
+static stmt_ty ast_for_classdef(struct compiling *, const node *, asdl_seq *);
+
+static stmt_ty ast_for_with_stmt(struct compiling *, const node *, bool);
+static stmt_ty ast_for_for_stmt(struct compiling *, const node *, bool);
+
+/* Note different signature for ast_for_call */
+static expr_ty ast_for_call(struct compiling *, const node *, expr_ty,
+ const node *, const node *, const node *);
+
+static PyObject *parsenumber(struct compiling *, const char *);
+static expr_ty parsestrplus(struct compiling *, const node *n);
+static void get_last_end_pos(asdl_seq *, int *, int *);
+
+#define COMP_GENEXP 0
+#define COMP_LISTCOMP 1
+#define COMP_SETCOMP 2
+
+static int
+init_normalization(struct compiling *c)
+{
+ PyObject *m = PyImport_ImportModuleNoBlock("unicodedata");
+ if (!m)
+ return 0;
+ c->c_normalize = PyObject_GetAttrString(m, "normalize");
+ Py_DECREF(m);
+ if (!c->c_normalize)
+ return 0;
+ return 1;
+}
+
+static identifier
+new_identifier(const char *n, struct compiling *c)
+{
+ PyObject *id = PyUnicode_DecodeUTF8(n, strlen(n), NULL);
+ if (!id)
+ return NULL;
+ /* PyUnicode_DecodeUTF8 should always return a ready string. */
+ assert(PyUnicode_IS_READY(id));
+ /* Check whether there are non-ASCII characters in the
+ identifier; if so, normalize to NFKC. */
+ if (!PyUnicode_IS_ASCII(id)) {
+ PyObject *id2;
+ if (!c->c_normalize && !init_normalization(c)) {
+ Py_DECREF(id);
+ return NULL;
+ }
+ PyObject *form = PyUnicode_InternFromString("NFKC");
+ if (form == NULL) {
+ Py_DECREF(id);
+ return NULL;
+ }
+ PyObject *args[2] = {form, id};
+ id2 = _PyObject_FastCall(c->c_normalize, args, 2);
+ Py_DECREF(id);
+ Py_DECREF(form);
+ if (!id2)
+ return NULL;
+ if (!PyUnicode_Check(id2)) {
+ PyErr_Format(PyExc_TypeError,
+ "unicodedata.normalize() must return a string, not "
+ "%.200s",
+ _PyType_Name(Py_TYPE(id2)));
+ Py_DECREF(id2);
+ return NULL;
+ }
+ id = id2;
+ }
+ PyUnicode_InternInPlace(&id);
+ if (PyArena_AddPyObject(c->c_arena, id) < 0) {
+ Py_DECREF(id);
+ return NULL;
+ }
+ return id;
+}
+
+#define NEW_IDENTIFIER(n) new_identifier(STR(n), c)
+
+static int
+ast_error(struct compiling *c, const node *n, const char *errmsg, ...)
+{
+ PyObject *value, *errstr, *loc, *tmp;
+ va_list va;
+
+ va_start(va, errmsg);
+ errstr = PyUnicode_FromFormatV(errmsg, va);
+ va_end(va);
+ if (!errstr) {
+ return 0;
+ }
+ loc = PyErr_ProgramTextObject(c->c_filename, LINENO(n));
+ if (!loc) {
+ Py_INCREF(Py_None);
+ loc = Py_None;
+ }
+ tmp = Py_BuildValue("(OiiN)", c->c_filename, LINENO(n), n->n_col_offset + 1, loc);
+ if (!tmp) {
+ Py_DECREF(errstr);
+ return 0;
+ }
+ value = PyTuple_Pack(2, errstr, tmp);
+ Py_DECREF(errstr);
+ Py_DECREF(tmp);
+ if (value) {
+ PyErr_SetObject(PyExc_SyntaxError, value);
+ Py_DECREF(value);
+ }
+ return 0;
+}
+
+/* num_stmts() returns number of contained statements.
+
+ Use this routine to determine how big a sequence is needed for
+ the statements in a parse tree. Its raison d'etre is this bit of
+ grammar:
+
+ stmt: simple_stmt | compound_stmt
+ simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
+
+ A simple_stmt can contain multiple small_stmt elements joined
+ by semicolons. If the arg is a simple_stmt, the number of
+ small_stmt elements is returned.
+*/
+
+static string
+new_type_comment(const char *s, struct compiling *c)
+{
+ PyObject *res = PyUnicode_DecodeUTF8(s, strlen(s), NULL);
+ if (res == NULL)
+ return NULL;
+ if (PyArena_AddPyObject(c->c_arena, res) < 0) {
+ Py_DECREF(res);
+ return NULL;
+ }
+ return res;
+}
+#define NEW_TYPE_COMMENT(n) new_type_comment(STR(n), c)
+
+static int
+num_stmts(const node *n)
+{
+ int i, l;
+ node *ch;
+
+ switch (TYPE(n)) {
+ case single_input:
+ if (TYPE(CHILD(n, 0)) == NEWLINE)
+ return 0;
+ else
+ return num_stmts(CHILD(n, 0));
+ case file_input:
+ l = 0;
+ for (i = 0; i < NCH(n); i++) {
+ ch = CHILD(n, i);
+ if (TYPE(ch) == stmt)
+ l += num_stmts(ch);
+ }
+ return l;
+ case stmt:
+ return num_stmts(CHILD(n, 0));
+ case compound_stmt:
+ return 1;
+ case simple_stmt:
+ return NCH(n) / 2; /* Divide by 2 to remove count of semi-colons */
+ case suite:
+ case func_body_suite:
+ /* func_body_suite: simple_stmt | NEWLINE [TYPE_COMMENT NEWLINE] INDENT stmt+ DEDENT */
+ /* suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT */
+ if (NCH(n) == 1)
+ return num_stmts(CHILD(n, 0));
+ else {
+ i = 2;
+ l = 0;
+ if (TYPE(CHILD(n, 1)) == TYPE_COMMENT)
+ i += 2;
+ for (; i < (NCH(n) - 1); i++)
+ l += num_stmts(CHILD(n, i));
+ return l;
+ }
+ default: {
+ _Py_FatalErrorFormat(__func__, "Non-statement found: %d %d",
+ TYPE(n), NCH(n));
+ }
+ }
+ Py_UNREACHABLE();
+}
+
+/* Transform the CST rooted at node * to the appropriate AST
+*/
+
+mod_ty
+PyAST_FromNodeObject(const node *n, PyCompilerFlags *flags,
+ PyObject *filename, PyArena *arena)
+{
+ int i, j, k, num;
+ asdl_seq *stmts = NULL;
+ asdl_seq *type_ignores = NULL;
+ stmt_ty s;
+ node *ch;
+ struct compiling c;
+ mod_ty res = NULL;
+ asdl_seq *argtypes = NULL;
+ expr_ty ret, arg;
+
+ c.c_arena = arena;
+ /* borrowed reference */
+ c.c_filename = filename;
+ c.c_normalize = NULL;
+ c.c_feature_version = flags && (flags->cf_flags & PyCF_ONLY_AST) ?
+ flags->cf_feature_version : PY_MINOR_VERSION;
+
+ if (TYPE(n) == encoding_decl)
+ n = CHILD(n, 0);
+
+ k = 0;
+ switch (TYPE(n)) {
+ case file_input:
+ stmts = _Py_asdl_seq_new(num_stmts(n), arena);
+ if (!stmts)
+ goto out;
+ for (i = 0; i < NCH(n) - 1; i++) {
+ ch = CHILD(n, i);
+ if (TYPE(ch) == NEWLINE)
+ continue;
+ REQ(ch, stmt);
+ num = num_stmts(ch);
+ if (num == 1) {
+ s = ast_for_stmt(&c, ch);
+ if (!s)
+ goto out;
+ asdl_seq_SET(stmts, k++, s);
+ }
+ else {
+ ch = CHILD(ch, 0);
+ REQ(ch, simple_stmt);
+ for (j = 0; j < num; j++) {
+ s = ast_for_stmt(&c, CHILD(ch, j * 2));
+ if (!s)
+ goto out;
+ asdl_seq_SET(stmts, k++, s);
+ }
+ }
+ }
+
+ /* Type ignores are stored under the ENDMARKER in file_input. */
+ ch = CHILD(n, NCH(n) - 1);
+ REQ(ch, ENDMARKER);
+ num = NCH(ch);
+ type_ignores = _Py_asdl_seq_new(num, arena);
+ if (!type_ignores)
+ goto out;
+
+ for (i = 0; i < num; i++) {
+ string type_comment = new_type_comment(STR(CHILD(ch, i)), &c);
+ if (!type_comment)
+ goto out;
+ type_ignore_ty ti = TypeIgnore(LINENO(CHILD(ch, i)), type_comment, arena);
+ if (!ti)
+ goto out;
+ asdl_seq_SET(type_ignores, i, ti);
+ }
+
+ res = Module(stmts, type_ignores, arena);
+ break;
+ case eval_input: {
+ expr_ty testlist_ast;
+
+ /* XXX Why not comp_for here? */
+ testlist_ast = ast_for_testlist(&c, CHILD(n, 0));
+ if (!testlist_ast)
+ goto out;
+ res = Expression(testlist_ast, arena);
+ break;
+ }
+ case single_input:
+ if (TYPE(CHILD(n, 0)) == NEWLINE) {
+ stmts = _Py_asdl_seq_new(1, arena);
+ if (!stmts)
+ goto out;
+ asdl_seq_SET(stmts, 0, Pass(n->n_lineno, n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset,
+ arena));
+ if (!asdl_seq_GET(stmts, 0))
+ goto out;
+ res = Interactive(stmts, arena);
+ }
+ else {
+ n = CHILD(n, 0);
+ num = num_stmts(n);
+ stmts = _Py_asdl_seq_new(num, arena);
+ if (!stmts)
+ goto out;
+ if (num == 1) {
+ s = ast_for_stmt(&c, n);
+ if (!s)
+ goto out;
+ asdl_seq_SET(stmts, 0, s);
+ }
+ else {
+ /* Only a simple_stmt can contain multiple statements. */
+ REQ(n, simple_stmt);
+ for (i = 0; i < NCH(n); i += 2) {
+ if (TYPE(CHILD(n, i)) == NEWLINE)
+ break;
+ s = ast_for_stmt(&c, CHILD(n, i));
+ if (!s)
+ goto out;
+ asdl_seq_SET(stmts, i / 2, s);
+ }
+ }
+
+ res = Interactive(stmts, arena);
+ }
+ break;
+ case func_type_input:
+ n = CHILD(n, 0);
+ REQ(n, func_type);
+
+ if (TYPE(CHILD(n, 1)) == typelist) {
+ ch = CHILD(n, 1);
+ /* this is overly permissive -- we don't pay any attention to
+ * stars on the args -- just parse them into an ordered list */
+ num = 0;
+ for (i = 0; i < NCH(ch); i++) {
+ if (TYPE(CHILD(ch, i)) == test) {
+ num++;
+ }
+ }
+
+ argtypes = _Py_asdl_seq_new(num, arena);
+ if (!argtypes)
+ goto out;
+
+ j = 0;
+ for (i = 0; i < NCH(ch); i++) {
+ if (TYPE(CHILD(ch, i)) == test) {
+ arg = ast_for_expr(&c, CHILD(ch, i));
+ if (!arg)
+ goto out;
+ asdl_seq_SET(argtypes, j++, arg);
+ }
+ }
+ }
+ else {
+ argtypes = _Py_asdl_seq_new(0, arena);
+ if (!argtypes)
+ goto out;
+ }
+
+ ret = ast_for_expr(&c, CHILD(n, NCH(n) - 1));
+ if (!ret)
+ goto out;
+ res = FunctionType(argtypes, ret, arena);
+ break;
+ default:
+ PyErr_Format(PyExc_SystemError,
+ "invalid node %d for PyAST_FromNode", TYPE(n));
+ goto out;
+ }
+ out:
+ if (c.c_normalize) {
+ Py_DECREF(c.c_normalize);
+ }
+ return res;
+}
+
+mod_ty
+PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename_str,
+ PyArena *arena)
+{
+ mod_ty mod;
+ PyObject *filename;
+ filename = PyUnicode_DecodeFSDefault(filename_str);
+ if (filename == NULL)
+ return NULL;
+ mod = PyAST_FromNodeObject(n, flags, filename, arena);
+ Py_DECREF(filename);
+ return mod;
+
+}
+
+/* Return the AST repr. of the operator represented as syntax (|, ^, etc.)
+*/
+
+static operator_ty
+get_operator(struct compiling *c, const node *n)
+{
+ switch (TYPE(n)) {
+ case VBAR:
+ return BitOr;
+ case CIRCUMFLEX:
+ return BitXor;
+ case AMPER:
+ return BitAnd;
+ case LEFTSHIFT:
+ return LShift;
+ case RIGHTSHIFT:
+ return RShift;
+ case PLUS:
+ return Add;
+ case MINUS:
+ return Sub;
+ case STAR:
+ return Mult;
+ case AT:
+ if (c->c_feature_version < 5) {
+ ast_error(c, n,
+ "The '@' operator is only supported in Python 3.5 and greater");
+ return (operator_ty)0;
+ }
+ return MatMult;
+ case SLASH:
+ return Div;
+ case DOUBLESLASH:
+ return FloorDiv;
+ case PERCENT:
+ return Mod;
+ default:
+ return (operator_ty)0;
+ }
+}
+
+static const char * const FORBIDDEN[] = {
+ "None",
+ "True",
+ "False",
+ "__debug__",
+ NULL,
+};
+
+static int
+forbidden_name(struct compiling *c, identifier name, const node *n,
+ int full_checks)
+{
+ assert(PyUnicode_Check(name));
+ const char * const *p = FORBIDDEN;
+ if (!full_checks) {
+ /* In most cases, the parser will protect True, False, and None
+ from being assign to. */
+ p += 3;
+ }
+ for (; *p; p++) {
+ if (_PyUnicode_EqualToASCIIString(name, *p)) {
+ ast_error(c, n, "cannot assign to %U", name);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static expr_ty
+copy_location(expr_ty e, const node *n, const node *end)
+{
+ if (e) {
+ e->lineno = LINENO(n);
+ e->col_offset = n->n_col_offset;
+ e->end_lineno = end->n_end_lineno;
+ e->end_col_offset = end->n_end_col_offset;
+ }
+ return e;
+}
+
+static const char *
+get_expr_name(expr_ty e)
+{
+ switch (e->kind) {
+ case Attribute_kind:
+ return "attribute";
+ case Subscript_kind:
+ return "subscript";
+ case Starred_kind:
+ return "starred";
+ case Name_kind:
+ return "name";
+ case List_kind:
+ return "list";
+ case Tuple_kind:
+ return "tuple";
+ case Lambda_kind:
+ return "lambda";
+ case Call_kind:
+ return "function call";
+ case BoolOp_kind:
+ case BinOp_kind:
+ case UnaryOp_kind:
+ return "operator";
+ case GeneratorExp_kind:
+ return "generator expression";
+ case Yield_kind:
+ case YieldFrom_kind:
+ return "yield expression";
+ case Await_kind:
+ return "await expression";
+ case ListComp_kind:
+ return "list comprehension";
+ case SetComp_kind:
+ return "set comprehension";
+ case DictComp_kind:
+ return "dict comprehension";
+ case Dict_kind:
+ return "dict display";
+ case Set_kind:
+ return "set display";
+ case JoinedStr_kind:
+ case FormattedValue_kind:
+ return "f-string expression";
+ case Constant_kind: {
+ PyObject *value = e->v.Constant.value;
+ if (value == Py_None) {
+ return "None";
+ }
+ if (value == Py_False) {
+ return "False";
+ }
+ if (value == Py_True) {
+ return "True";
+ }
+ if (value == Py_Ellipsis) {
+ return "Ellipsis";
+ }
+ return "literal";
+ }
+ case Compare_kind:
+ return "comparison";
+ case IfExp_kind:
+ return "conditional expression";
+ case NamedExpr_kind:
+ return "named expression";
+ default:
+ PyErr_Format(PyExc_SystemError,
+ "unexpected expression in assignment %d (line %d)",
+ e->kind, e->lineno);
+ return NULL;
+ }
+}
+
+/* Set the context ctx for expr_ty e, recursively traversing e.
+
+ Only sets context for expr kinds that "can appear in assignment context"
+ (according to ../Parser/Python.asdl). For other expr kinds, it sets
+ an appropriate syntax error and returns false.
+*/
+
+static int
+set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n)
+{
+ asdl_seq *s = NULL;
+
+ /* Expressions in an augmented assignment have a Store context. */
+
+ switch (e->kind) {
+ case Attribute_kind:
+ e->v.Attribute.ctx = ctx;
+ if (ctx == Store && forbidden_name(c, e->v.Attribute.attr, n, 1))
+ return 0;
+ break;
+ case Subscript_kind:
+ e->v.Subscript.ctx = ctx;
+ break;
+ case Starred_kind:
+ e->v.Starred.ctx = ctx;
+ if (!set_context(c, e->v.Starred.value, ctx, n))
+ return 0;
+ break;
+ case Name_kind:
+ if (ctx == Store) {
+ if (forbidden_name(c, e->v.Name.id, n, 0))
+ return 0; /* forbidden_name() calls ast_error() */
+ }
+ e->v.Name.ctx = ctx;
+ break;
+ case List_kind:
+ e->v.List.ctx = ctx;
+ s = e->v.List.elts;
+ break;
+ case Tuple_kind:
+ e->v.Tuple.ctx = ctx;
+ s = e->v.Tuple.elts;
+ break;
+ default: {
+ const char *expr_name = get_expr_name(e);
+ if (expr_name != NULL) {
+ ast_error(c, n, "cannot %s %s",
+ ctx == Store ? "assign to" : "delete",
+ expr_name);
+ }
+ return 0;
+ }
+ }
+
+ /* If the LHS is a list or tuple, we need to set the assignment
+ context for all the contained elements.
+ */
+ if (s) {
+ Py_ssize_t i;
+
+ for (i = 0; i < asdl_seq_LEN(s); i++) {
+ if (!set_context(c, (expr_ty)asdl_seq_GET(s, i), ctx, n))
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static operator_ty
+ast_for_augassign(struct compiling *c, const node *n)
+{
+ REQ(n, augassign);
+ n = CHILD(n, 0);
+ switch (STR(n)[0]) {
+ case '+':
+ return Add;
+ case '-':
+ return Sub;
+ case '/':
+ if (STR(n)[1] == '/')
+ return FloorDiv;
+ else
+ return Div;
+ case '%':
+ return Mod;
+ case '<':
+ return LShift;
+ case '>':
+ return RShift;
+ case '&':
+ return BitAnd;
+ case '^':
+ return BitXor;
+ case '|':
+ return BitOr;
+ case '*':
+ if (STR(n)[1] == '*')
+ return Pow;
+ else
+ return Mult;
+ case '@':
+ if (c->c_feature_version < 5) {
+ ast_error(c, n,
+ "The '@' operator is only supported in Python 3.5 and greater");
+ return (operator_ty)0;
+ }
+ return MatMult;
+ default:
+ PyErr_Format(PyExc_SystemError, "invalid augassign: %s", STR(n));
+ return (operator_ty)0;
+ }
+}
+
+static cmpop_ty
+ast_for_comp_op(struct compiling *c, const node *n)
+{
+ /* comp_op: '<'|'>'|'=='|'>='|'<='|'!='|'in'|'not' 'in'|'is'
+ |'is' 'not'
+ */
+ REQ(n, comp_op);
+ if (NCH(n) == 1) {
+ n = CHILD(n, 0);
+ switch (TYPE(n)) {
+ case LESS:
+ return Lt;
+ case GREATER:
+ return Gt;
+ case EQEQUAL: /* == */
+ return Eq;
+ case LESSEQUAL:
+ return LtE;
+ case GREATEREQUAL:
+ return GtE;
+ case NOTEQUAL:
+ return NotEq;
+ case NAME:
+ if (strcmp(STR(n), "in") == 0)
+ return In;
+ if (strcmp(STR(n), "is") == 0)
+ return Is;
+ /* fall through */
+ default:
+ PyErr_Format(PyExc_SystemError, "invalid comp_op: %s",
+ STR(n));
+ return (cmpop_ty)0;
+ }
+ }
+ else if (NCH(n) == 2) {
+ /* handle "not in" and "is not" */
+ switch (TYPE(CHILD(n, 0))) {
+ case NAME:
+ if (strcmp(STR(CHILD(n, 1)), "in") == 0)
+ return NotIn;
+ if (strcmp(STR(CHILD(n, 0)), "is") == 0)
+ return IsNot;
+ /* fall through */
+ default:
+ PyErr_Format(PyExc_SystemError, "invalid comp_op: %s %s",
+ STR(CHILD(n, 0)), STR(CHILD(n, 1)));
+ return (cmpop_ty)0;
+ }
+ }
+ PyErr_Format(PyExc_SystemError, "invalid comp_op: has %d children",
+ NCH(n));
+ return (cmpop_ty)0;
+}
+
+static asdl_seq *
+seq_for_testlist(struct compiling *c, const node *n)
+{
+ /* testlist: test (',' test)* [',']
+ testlist_star_expr: test|star_expr (',' test|star_expr)* [',']
+ */
+ asdl_seq *seq;
+ expr_ty expression;
+ int i;
+ assert(TYPE(n) == testlist || TYPE(n) == testlist_star_expr || TYPE(n) == testlist_comp);
+
+ seq = _Py_asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
+ if (!seq)
+ return NULL;
+
+ for (i = 0; i < NCH(n); i += 2) {
+ const node *ch = CHILD(n, i);
+ assert(TYPE(ch) == test || TYPE(ch) == test_nocond || TYPE(ch) == star_expr || TYPE(ch) == namedexpr_test);
+
+ expression = ast_for_expr(c, ch);
+ if (!expression)
+ return NULL;
+
+ assert(i / 2 < seq->size);
+ asdl_seq_SET(seq, i / 2, expression);
+ }
+ return seq;
+}
+
+static arg_ty
+ast_for_arg(struct compiling *c, const node *n)
+{
+ identifier name;
+ expr_ty annotation = NULL;
+ node *ch;
+ arg_ty ret;
+
+ assert(TYPE(n) == tfpdef || TYPE(n) == vfpdef);
+ ch = CHILD(n, 0);
+ name = NEW_IDENTIFIER(ch);
+ if (!name)
+ return NULL;
+ if (forbidden_name(c, name, ch, 0))
+ return NULL;
+
+ if (NCH(n) == 3 && TYPE(CHILD(n, 1)) == COLON) {
+ annotation = ast_for_expr(c, CHILD(n, 2));
+ if (!annotation)
+ return NULL;
+ }
+
+ ret = arg(name, annotation, NULL, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ if (!ret)
+ return NULL;
+ return ret;
+}
+
+/* returns -1 if failed to handle keyword only arguments
+ returns new position to keep processing if successful
+ (',' tfpdef ['=' test])*
+ ^^^
+ start pointing here
+ */
+static int
+handle_keywordonly_args(struct compiling *c, const node *n, int start,
+ asdl_seq *kwonlyargs, asdl_seq *kwdefaults)
+{
+ PyObject *argname;
+ node *ch;
+ expr_ty expression, annotation;
+ arg_ty arg = NULL;
+ int i = start;
+ int j = 0; /* index for kwdefaults and kwonlyargs */
+
+ if (kwonlyargs == NULL) {
+ ast_error(c, CHILD(n, start), "named arguments must follow bare *");
+ return -1;
+ }
+ assert(kwdefaults != NULL);
+ while (i < NCH(n)) {
+ ch = CHILD(n, i);
+ switch (TYPE(ch)) {
+ case vfpdef:
+ case tfpdef:
+ if (i + 1 < NCH(n) && TYPE(CHILD(n, i + 1)) == EQUAL) {
+ expression = ast_for_expr(c, CHILD(n, i + 2));
+ if (!expression)
+ goto error;
+ asdl_seq_SET(kwdefaults, j, expression);
+ i += 2; /* '=' and test */
+ }
+ else { /* setting NULL if no default value exists */
+ asdl_seq_SET(kwdefaults, j, NULL);
+ }
+ if (NCH(ch) == 3) {
+ /* ch is NAME ':' test */
+ annotation = ast_for_expr(c, CHILD(ch, 2));
+ if (!annotation)
+ goto error;
+ }
+ else {
+ annotation = NULL;
+ }
+ ch = CHILD(ch, 0);
+ argname = NEW_IDENTIFIER(ch);
+ if (!argname)
+ goto error;
+ if (forbidden_name(c, argname, ch, 0))
+ goto error;
+ arg = arg(argname, annotation, NULL, LINENO(ch), ch->n_col_offset,
+ ch->n_end_lineno, ch->n_end_col_offset,
+ c->c_arena);
+ if (!arg)
+ goto error;
+ asdl_seq_SET(kwonlyargs, j++, arg);
+ i += 1; /* the name */
+ if (i < NCH(n) && TYPE(CHILD(n, i)) == COMMA)
+ i += 1; /* the comma, if present */
+ break;
+ case TYPE_COMMENT:
+ /* arg will be equal to the last argument processed */
+ arg->type_comment = NEW_TYPE_COMMENT(ch);
+ if (!arg->type_comment)
+ goto error;
+ i += 1;
+ break;
+ case DOUBLESTAR:
+ return i;
+ default:
+ ast_error(c, ch, "unexpected node");
+ goto error;
+ }
+ }
+ return i;
+ error:
+ return -1;
+}
+
+/* Create AST for argument list. */
+
+static arguments_ty
+ast_for_arguments(struct compiling *c, const node *n)
+{
+ /* This function handles both typedargslist (function definition)
+ and varargslist (lambda definition).
+
+ parameters: '(' [typedargslist] ')'
+
+ The following definition for typedarglist is equivalent to this set of rules:
+
+ arguments = argument (',' [TYPE_COMMENT] argument)*
+ argument = tfpdef ['=' test]
+ kwargs = '**' tfpdef [','] [TYPE_COMMENT]
+ args = '*' [tfpdef]
+ kwonly_kwargs = (',' [TYPE_COMMENT] argument)* (TYPE_COMMENT | [','
+ [TYPE_COMMENT] [kwargs]])
+ args_kwonly_kwargs = args kwonly_kwargs | kwargs
+ poskeyword_args_kwonly_kwargs = arguments ( TYPE_COMMENT | [','
+ [TYPE_COMMENT] [args_kwonly_kwargs]])
+ typedargslist_no_posonly = poskeyword_args_kwonly_kwargs | args_kwonly_kwargs
+ typedarglist = (arguments ',' [TYPE_COMMENT] '/' [',' [[TYPE_COMMENT]
+ typedargslist_no_posonly]])|(typedargslist_no_posonly)"
+
+ typedargslist: ( (tfpdef ['=' test] (',' [TYPE_COMMENT] tfpdef ['=' test])*
+ ',' [TYPE_COMMENT] '/' [',' [ [TYPE_COMMENT] tfpdef ['=' test] ( ','
+ [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' [TYPE_COMMENT] [ '*'
+ [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [','
+ [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) | '**' tfpdef [',']
+ [TYPE_COMMENT]]]) | '*' [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])*
+ (TYPE_COMMENT | [',' [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) |
+ '**' tfpdef [','] [TYPE_COMMENT]]] ) | (tfpdef ['=' test] (','
+ [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' [TYPE_COMMENT] [ '*'
+ [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [','
+ [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) | '**' tfpdef [',']
+ [TYPE_COMMENT]]]) | '*' [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])*
+ (TYPE_COMMENT | [',' [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) |
+ '**' tfpdef [','] [TYPE_COMMENT]))
+
+ tfpdef: NAME [':' test]
+
+ The following definition for varargslist is equivalent to this set of rules:
+
+ arguments = argument (',' argument )*
+ argument = vfpdef ['=' test]
+ kwargs = '**' vfpdef [',']
+ args = '*' [vfpdef]
+ kwonly_kwargs = (',' argument )* [',' [kwargs]]
+ args_kwonly_kwargs = args kwonly_kwargs | kwargs
+ poskeyword_args_kwonly_kwargs = arguments [',' [args_kwonly_kwargs]]
+ vararglist_no_posonly = poskeyword_args_kwonly_kwargs | args_kwonly_kwargs
+ varargslist = arguments ',' '/' [','[(vararglist_no_posonly)]] |
+ (vararglist_no_posonly)
+
+ varargslist: vfpdef ['=' test ](',' vfpdef ['=' test])* ',' '/' [',' [ (vfpdef ['='
+ test] (',' vfpdef ['=' test])* [',' [ '*' [vfpdef] (',' vfpdef ['=' test])* [','
+ ['**' vfpdef [',']]] | '**' vfpdef [',']]] | '*' [vfpdef] (',' vfpdef ['=' test])*
+ [',' ['**' vfpdef [',']]] | '**' vfpdef [',']) ]] | (vfpdef ['=' test] (',' vfpdef
+ ['=' test])* [',' [ '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]]
+ | '**' vfpdef [',']]] | '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef
+ [',']]] | '**' vfpdef [','])
+
+ vfpdef: NAME
+
+ */
+ int i, j, k, l, nposonlyargs=0, nposargs = 0, nkwonlyargs = 0;
+ int nposdefaults = 0, found_default = 0;
+ asdl_seq *posonlyargs, *posargs, *posdefaults, *kwonlyargs, *kwdefaults;
+ arg_ty vararg = NULL, kwarg = NULL;
+ arg_ty arg = NULL;
+ node *ch;
+
+ if (TYPE(n) == parameters) {
+ if (NCH(n) == 2) /* () as argument list */
+ return arguments(NULL, NULL, NULL, NULL, NULL, NULL, NULL, c->c_arena);
+ n = CHILD(n, 1);
+ }
+ assert(TYPE(n) == typedargslist || TYPE(n) == varargslist);
+
+ /* First count the number of positional args & defaults. The
+ variable i is the loop index for this for loop and the next.
+ The next loop picks up where the first leaves off.
+ */
+ for (i = 0; i < NCH(n); i++) {
+ ch = CHILD(n, i);
+ if (TYPE(ch) == STAR) {
+ /* skip star */
+ i++;
+ if (i < NCH(n) && /* skip argument following star */
+ (TYPE(CHILD(n, i)) == tfpdef ||
+ TYPE(CHILD(n, i)) == vfpdef)) {
+ i++;
+ }
+ break;
+ }
+ if (TYPE(ch) == DOUBLESTAR) break;
+ if (TYPE(ch) == vfpdef || TYPE(ch) == tfpdef) nposargs++;
+ if (TYPE(ch) == EQUAL) nposdefaults++;
+ if (TYPE(ch) == SLASH ) {
+ nposonlyargs = nposargs;
+ nposargs = 0;
+ }
+ }
+ /* count the number of keyword only args &
+ defaults for keyword only args */
+ for ( ; i < NCH(n); ++i) {
+ ch = CHILD(n, i);
+ if (TYPE(ch) == DOUBLESTAR) break;
+ if (TYPE(ch) == tfpdef || TYPE(ch) == vfpdef) nkwonlyargs++;
+ }
+ posonlyargs = (nposonlyargs ? _Py_asdl_seq_new(nposonlyargs, c->c_arena) : NULL);
+ if (!posonlyargs && nposonlyargs) {
+ return NULL;
+ }
+ posargs = (nposargs ? _Py_asdl_seq_new(nposargs, c->c_arena) : NULL);
+ if (!posargs && nposargs)
+ return NULL;
+ kwonlyargs = (nkwonlyargs ?
+ _Py_asdl_seq_new(nkwonlyargs, c->c_arena) : NULL);
+ if (!kwonlyargs && nkwonlyargs)
+ return NULL;
+ posdefaults = (nposdefaults ?
+ _Py_asdl_seq_new(nposdefaults, c->c_arena) : NULL);
+ if (!posdefaults && nposdefaults)
+ return NULL;
+ /* The length of kwonlyargs and kwdefaults are same
+ since we set NULL as default for keyword only argument w/o default
+ - we have sequence data structure, but no dictionary */
+ kwdefaults = (nkwonlyargs ?
+ _Py_asdl_seq_new(nkwonlyargs, c->c_arena) : NULL);
+ if (!kwdefaults && nkwonlyargs)
+ return NULL;
+
+ /* tfpdef: NAME [':' test]
+ vfpdef: NAME
+ */
+ i = 0;
+ j = 0; /* index for defaults */
+ k = 0; /* index for args */
+ l = 0; /* index for posonlyargs */
+ while (i < NCH(n)) {
+ ch = CHILD(n, i);
+ switch (TYPE(ch)) {
+ case tfpdef:
+ case vfpdef:
+ /* XXX Need to worry about checking if TYPE(CHILD(n, i+1)) is
+ anything other than EQUAL or a comma? */
+ /* XXX Should NCH(n) check be made a separate check? */
+ if (i + 1 < NCH(n) && TYPE(CHILD(n, i + 1)) == EQUAL) {
+ expr_ty expression = ast_for_expr(c, CHILD(n, i + 2));
+ if (!expression)
+ return NULL;
+ assert(posdefaults != NULL);
+ asdl_seq_SET(posdefaults, j++, expression);
+ i += 2;
+ found_default = 1;
+ }
+ else if (found_default) {
+ ast_error(c, n,
+ "non-default argument follows default argument");
+ return NULL;
+ }
+ arg = ast_for_arg(c, ch);
+ if (!arg)
+ return NULL;
+ if (l < nposonlyargs) {
+ asdl_seq_SET(posonlyargs, l++, arg);
+ } else {
+ asdl_seq_SET(posargs, k++, arg);
+ }
+ i += 1; /* the name */
+ if (i < NCH(n) && TYPE(CHILD(n, i)) == COMMA)
+ i += 1; /* the comma, if present */
+ break;
+ case SLASH:
+ /* Advance the slash and the comma. If there are more names
+ * after the slash there will be a comma so we are advancing
+ * the correct number of nodes. If the slash is the last item,
+ * we will be advancing an extra token but then * i > NCH(n)
+ * and the enclosing while will finish correctly. */
+ i += 2;
+ break;
+ case STAR:
+ if (i+1 >= NCH(n) ||
+ (i+2 == NCH(n) && (TYPE(CHILD(n, i+1)) == COMMA
+ || TYPE(CHILD(n, i+1)) == TYPE_COMMENT))) {
+ ast_error(c, CHILD(n, i),
+ "named arguments must follow bare *");
+ return NULL;
+ }
+ ch = CHILD(n, i+1); /* tfpdef or COMMA */
+ if (TYPE(ch) == COMMA) {
+ int res = 0;
+ i += 2; /* now follows keyword only arguments */
+
+ if (i < NCH(n) && TYPE(CHILD(n, i)) == TYPE_COMMENT) {
+ ast_error(c, CHILD(n, i),
+ "bare * has associated type comment");
+ return NULL;
+ }
+
+ res = handle_keywordonly_args(c, n, i,
+ kwonlyargs, kwdefaults);
+ if (res == -1) return NULL;
+ i = res; /* res has new position to process */
+ }
+ else {
+ vararg = ast_for_arg(c, ch);
+ if (!vararg)
+ return NULL;
+
+ i += 2; /* the star and the name */
+ if (i < NCH(n) && TYPE(CHILD(n, i)) == COMMA)
+ i += 1; /* the comma, if present */
+
+ if (i < NCH(n) && TYPE(CHILD(n, i)) == TYPE_COMMENT) {
+ vararg->type_comment = NEW_TYPE_COMMENT(CHILD(n, i));
+ if (!vararg->type_comment)
+ return NULL;
+ i += 1;
+ }
+
+ if (i < NCH(n) && (TYPE(CHILD(n, i)) == tfpdef
+ || TYPE(CHILD(n, i)) == vfpdef)) {
+ int res = 0;
+ res = handle_keywordonly_args(c, n, i,
+ kwonlyargs, kwdefaults);
+ if (res == -1) return NULL;
+ i = res; /* res has new position to process */
+ }
+ }
+ break;
+ case DOUBLESTAR:
+ ch = CHILD(n, i+1); /* tfpdef */
+ assert(TYPE(ch) == tfpdef || TYPE(ch) == vfpdef);
+ kwarg = ast_for_arg(c, ch);
+ if (!kwarg)
+ return NULL;
+ i += 2; /* the double star and the name */
+ if (i < NCH(n) && TYPE(CHILD(n, i)) == COMMA)
+ i += 1; /* the comma, if present */
+ break;
+ case TYPE_COMMENT:
+ assert(i);
+
+ if (kwarg)
+ arg = kwarg;
+
+ /* arg will be equal to the last argument processed */
+ arg->type_comment = NEW_TYPE_COMMENT(ch);
+ if (!arg->type_comment)
+ return NULL;
+ i += 1;
+ break;
+ default:
+ PyErr_Format(PyExc_SystemError,
+ "unexpected node in varargslist: %d @ %d",
+ TYPE(ch), i);
+ return NULL;
+ }
+ }
+ return arguments(posonlyargs, posargs, vararg, kwonlyargs, kwdefaults, kwarg, posdefaults, c->c_arena);
+}
+
+static expr_ty
+ast_for_decorator(struct compiling *c, const node *n)
+{
+ /* decorator: '@' namedexpr_test NEWLINE */
+
+ REQ(n, decorator);
+ REQ(CHILD(n, 0), AT);
+ REQ(CHILD(n, 2), NEWLINE);
+
+ return ast_for_expr(c, CHILD(n, 1));
+}
+
+static asdl_seq*
+ast_for_decorators(struct compiling *c, const node *n)
+{
+ asdl_seq* decorator_seq;
+ expr_ty d;
+ int i;
+
+ REQ(n, decorators);
+ decorator_seq = _Py_asdl_seq_new(NCH(n), c->c_arena);
+ if (!decorator_seq)
+ return NULL;
+
+ for (i = 0; i < NCH(n); i++) {
+ d = ast_for_decorator(c, CHILD(n, i));
+ if (!d)
+ return NULL;
+ asdl_seq_SET(decorator_seq, i, d);
+ }
+ return decorator_seq;
+}
+
+static stmt_ty
+ast_for_funcdef_impl(struct compiling *c, const node *n0,
+ asdl_seq *decorator_seq, bool is_async)
+{
+ /* funcdef: 'def' NAME parameters ['->' test] ':' [TYPE_COMMENT] suite */
+ const node * const n = is_async ? CHILD(n0, 1) : n0;
+ identifier name;
+ arguments_ty args;
+ asdl_seq *body;
+ expr_ty returns = NULL;
+ int name_i = 1;
+ int end_lineno, end_col_offset;
+ node *tc;
+ string type_comment = NULL;
+
+ if (is_async && c->c_feature_version < 5) {
+ ast_error(c, n,
+ "Async functions are only supported in Python 3.5 and greater");
+ return NULL;
+ }
+
+ REQ(n, funcdef);
+
+ name = NEW_IDENTIFIER(CHILD(n, name_i));
+ if (!name)
+ return NULL;
+ if (forbidden_name(c, name, CHILD(n, name_i), 0))
+ return NULL;
+ args = ast_for_arguments(c, CHILD(n, name_i + 1));
+ if (!args)
+ return NULL;
+ if (TYPE(CHILD(n, name_i+2)) == RARROW) {
+ returns = ast_for_expr(c, CHILD(n, name_i + 3));
+ if (!returns)
+ return NULL;
+ name_i += 2;
+ }
+ if (TYPE(CHILD(n, name_i + 3)) == TYPE_COMMENT) {
+ type_comment = NEW_TYPE_COMMENT(CHILD(n, name_i + 3));
+ if (!type_comment)
+ return NULL;
+ name_i += 1;
+ }
+ body = ast_for_suite(c, CHILD(n, name_i + 3));
+ if (!body)
+ return NULL;
+ get_last_end_pos(body, &end_lineno, &end_col_offset);
+
+ if (NCH(CHILD(n, name_i + 3)) > 1) {
+ /* Check if the suite has a type comment in it. */
+ tc = CHILD(CHILD(n, name_i + 3), 1);
+
+ if (TYPE(tc) == TYPE_COMMENT) {
+ if (type_comment != NULL) {
+ ast_error(c, n, "Cannot have two type comments on def");
+ return NULL;
+ }
+ type_comment = NEW_TYPE_COMMENT(tc);
+ if (!type_comment)
+ return NULL;
+ }
+ }
+
+ if (is_async)
+ return AsyncFunctionDef(name, args, body, decorator_seq, returns, type_comment,
+ LINENO(n0), n0->n_col_offset, end_lineno, end_col_offset, c->c_arena);
+ else
+ return FunctionDef(name, args, body, decorator_seq, returns, type_comment,
+ LINENO(n), n->n_col_offset, end_lineno, end_col_offset, c->c_arena);
+}
+
+static stmt_ty
+ast_for_async_funcdef(struct compiling *c, const node *n, asdl_seq *decorator_seq)
+{
+ /* async_funcdef: ASYNC funcdef */
+ REQ(n, async_funcdef);
+ REQ(CHILD(n, 0), ASYNC);
+ REQ(CHILD(n, 1), funcdef);
+
+ return ast_for_funcdef_impl(c, n, decorator_seq,
+ true /* is_async */);
+}
+
+static stmt_ty
+ast_for_funcdef(struct compiling *c, const node *n, asdl_seq *decorator_seq)
+{
+ /* funcdef: 'def' NAME parameters ['->' test] ':' suite */
+ return ast_for_funcdef_impl(c, n, decorator_seq,
+ false /* is_async */);
+}
+
+
+static stmt_ty
+ast_for_async_stmt(struct compiling *c, const node *n)
+{
+ /* async_stmt: ASYNC (funcdef | with_stmt | for_stmt) */
+ REQ(n, async_stmt);
+ REQ(CHILD(n, 0), ASYNC);
+
+ switch (TYPE(CHILD(n, 1))) {
+ case funcdef:
+ return ast_for_funcdef_impl(c, n, NULL,
+ true /* is_async */);
+ case with_stmt:
+ return ast_for_with_stmt(c, n,
+ true /* is_async */);
+
+ case for_stmt:
+ return ast_for_for_stmt(c, n,
+ true /* is_async */);
+
+ default:
+ PyErr_Format(PyExc_SystemError,
+ "invalid async stament: %s",
+ STR(CHILD(n, 1)));
+ return NULL;
+ }
+}
+
+static stmt_ty
+ast_for_decorated(struct compiling *c, const node *n)
+{
+ /* decorated: decorators (classdef | funcdef | async_funcdef) */
+ stmt_ty thing = NULL;
+ asdl_seq *decorator_seq = NULL;
+
+ REQ(n, decorated);
+
+ decorator_seq = ast_for_decorators(c, CHILD(n, 0));
+ if (!decorator_seq)
+ return NULL;
+
+ assert(TYPE(CHILD(n, 1)) == funcdef ||
+ TYPE(CHILD(n, 1)) == async_funcdef ||
+ TYPE(CHILD(n, 1)) == classdef);
+
+ if (TYPE(CHILD(n, 1)) == funcdef) {
+ thing = ast_for_funcdef(c, CHILD(n, 1), decorator_seq);
+ } else if (TYPE(CHILD(n, 1)) == classdef) {
+ thing = ast_for_classdef(c, CHILD(n, 1), decorator_seq);
+ } else if (TYPE(CHILD(n, 1)) == async_funcdef) {
+ thing = ast_for_async_funcdef(c, CHILD(n, 1), decorator_seq);
+ }
+ return thing;
+}
+
+static expr_ty
+ast_for_namedexpr(struct compiling *c, const node *n)
+{
+ /* namedexpr_test: test [':=' test]
+ argument: ( test [comp_for] |
+ test ':=' test |
+ test '=' test |
+ '**' test |
+ '*' test )
+ */
+ expr_ty target, value;
+
+ target = ast_for_expr(c, CHILD(n, 0));
+ if (!target)
+ return NULL;
+
+ value = ast_for_expr(c, CHILD(n, 2));
+ if (!value)
+ return NULL;
+
+ if (target->kind != Name_kind) {
+ const char *expr_name = get_expr_name(target);
+ if (expr_name != NULL) {
+ ast_error(c, n, "cannot use assignment expressions with %s", expr_name);
+ }
+ return NULL;
+ }
+
+ if (!set_context(c, target, Store, n))
+ return NULL;
+
+ return NamedExpr(target, value, LINENO(n), n->n_col_offset, n->n_end_lineno,
+ n->n_end_col_offset, c->c_arena);
+}
+
+static expr_ty
+ast_for_lambdef(struct compiling *c, const node *n)
+{
+ /* lambdef: 'lambda' [varargslist] ':' test
+ lambdef_nocond: 'lambda' [varargslist] ':' test_nocond */
+ arguments_ty args;
+ expr_ty expression;
+
+ if (NCH(n) == 3) {
+ args = arguments(NULL, NULL, NULL, NULL, NULL, NULL, NULL, c->c_arena);
+ if (!args)
+ return NULL;
+ expression = ast_for_expr(c, CHILD(n, 2));
+ if (!expression)
+ return NULL;
+ }
+ else {
+ args = ast_for_arguments(c, CHILD(n, 1));
+ if (!args)
+ return NULL;
+ expression = ast_for_expr(c, CHILD(n, 3));
+ if (!expression)
+ return NULL;
+ }
+
+ return Lambda(args, expression, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+}
+
+static expr_ty
+ast_for_ifexpr(struct compiling *c, const node *n)
+{
+ /* test: or_test 'if' or_test 'else' test */
+ expr_ty expression, body, orelse;
+
+ assert(NCH(n) == 5);
+ body = ast_for_expr(c, CHILD(n, 0));
+ if (!body)
+ return NULL;
+ expression = ast_for_expr(c, CHILD(n, 2));
+ if (!expression)
+ return NULL;
+ orelse = ast_for_expr(c, CHILD(n, 4));
+ if (!orelse)
+ return NULL;
+ return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset,
+ c->c_arena);
+}
+
+/*
+ Count the number of 'for' loops in a comprehension.
+
+ Helper for ast_for_comprehension().
+*/
+
+static int
+count_comp_fors(struct compiling *c, const node *n)
+{
+ int n_fors = 0;
+
+ count_comp_for:
+ n_fors++;
+ REQ(n, comp_for);
+ if (NCH(n) == 2) {
+ REQ(CHILD(n, 0), ASYNC);
+ n = CHILD(n, 1);
+ }
+ else if (NCH(n) == 1) {
+ n = CHILD(n, 0);
+ }
+ else {
+ goto error;
+ }
+ if (NCH(n) == (5)) {
+ n = CHILD(n, 4);
+ }
+ else {
+ return n_fors;
+ }
+ count_comp_iter:
+ REQ(n, comp_iter);
+ n = CHILD(n, 0);
+ if (TYPE(n) == comp_for)
+ goto count_comp_for;
+ else if (TYPE(n) == comp_if) {
+ if (NCH(n) == 3) {
+ n = CHILD(n, 2);
+ goto count_comp_iter;
+ }
+ else
+ return n_fors;
+ }
+
+ error:
+ /* Should never be reached */
+ PyErr_SetString(PyExc_SystemError,
+ "logic error in count_comp_fors");
+ return -1;
+}
+
+/* Count the number of 'if' statements in a comprehension.
+
+ Helper for ast_for_comprehension().
+*/
+
+static int
+count_comp_ifs(struct compiling *c, const node *n)
+{
+ int n_ifs = 0;
+
+ while (1) {
+ REQ(n, comp_iter);
+ if (TYPE(CHILD(n, 0)) == comp_for)
+ return n_ifs;
+ n = CHILD(n, 0);
+ REQ(n, comp_if);
+ n_ifs++;
+ if (NCH(n) == 2)
+ return n_ifs;
+ n = CHILD(n, 2);
+ }
+}
+
+static asdl_seq *
+ast_for_comprehension(struct compiling *c, const node *n)
+{
+ int i, n_fors;
+ asdl_seq *comps;
+
+ n_fors = count_comp_fors(c, n);
+ if (n_fors == -1)
+ return NULL;
+
+ comps = _Py_asdl_seq_new(n_fors, c->c_arena);
+ if (!comps)
+ return NULL;
+
+ for (i = 0; i < n_fors; i++) {
+ comprehension_ty comp;
+ asdl_seq *t;
+ expr_ty expression, first;
+ node *for_ch;
+ node *sync_n;
+ int is_async = 0;
+
+ REQ(n, comp_for);
+
+ if (NCH(n) == 2) {
+ is_async = 1;
+ REQ(CHILD(n, 0), ASYNC);
+ sync_n = CHILD(n, 1);
+ }
+ else {
+ sync_n = CHILD(n, 0);
+ }
+ REQ(sync_n, sync_comp_for);
+
+ /* Async comprehensions only allowed in Python 3.6 and greater */
+ if (is_async && c->c_feature_version < 6) {
+ ast_error(c, n,
+ "Async comprehensions are only supported in Python 3.6 and greater");
+ return NULL;
+ }
+
+ for_ch = CHILD(sync_n, 1);
+ t = ast_for_exprlist(c, for_ch, Store);
+ if (!t)
+ return NULL;
+ expression = ast_for_expr(c, CHILD(sync_n, 3));
+ if (!expression)
+ return NULL;
+
+ /* Check the # of children rather than the length of t, since
+ (x for x, in ...) has 1 element in t, but still requires a Tuple. */
+ first = (expr_ty)asdl_seq_GET(t, 0);
+ if (NCH(for_ch) == 1)
+ comp = comprehension(first, expression, NULL,
+ is_async, c->c_arena);
+ else
+ comp = comprehension(Tuple(t, Store, first->lineno, first->col_offset,
+ for_ch->n_end_lineno, for_ch->n_end_col_offset,
+ c->c_arena),
+ expression, NULL, is_async, c->c_arena);
+ if (!comp)
+ return NULL;
+
+ if (NCH(sync_n) == 5) {
+ int j, n_ifs;
+ asdl_seq *ifs;
+
+ n = CHILD(sync_n, 4);
+ n_ifs = count_comp_ifs(c, n);
+ if (n_ifs == -1)
+ return NULL;
+
+ ifs = _Py_asdl_seq_new(n_ifs, c->c_arena);
+ if (!ifs)
+ return NULL;
+
+ for (j = 0; j < n_ifs; j++) {
+ REQ(n, comp_iter);
+ n = CHILD(n, 0);
+ REQ(n, comp_if);
+
+ expression = ast_for_expr(c, CHILD(n, 1));
+ if (!expression)
+ return NULL;
+ asdl_seq_SET(ifs, j, expression);
+ if (NCH(n) == 3)
+ n = CHILD(n, 2);
+ }
+ /* on exit, must guarantee that n is a comp_for */
+ if (TYPE(n) == comp_iter)
+ n = CHILD(n, 0);
+ comp->ifs = ifs;
+ }
+ asdl_seq_SET(comps, i, comp);
+ }
+ return comps;
+}
+
+static expr_ty
+ast_for_itercomp(struct compiling *c, const node *n, int type)
+{
+ /* testlist_comp: (test|star_expr)
+ * ( comp_for | (',' (test|star_expr))* [','] ) */
+ expr_ty elt;
+ asdl_seq *comps;
+ node *ch;
+
+ assert(NCH(n) > 1);
+
+ ch = CHILD(n, 0);
+ elt = ast_for_expr(c, ch);
+ if (!elt)
+ return NULL;
+ if (elt->kind == Starred_kind) {
+ ast_error(c, ch, "iterable unpacking cannot be used in comprehension");
+ return NULL;
+ }
+
+ comps = ast_for_comprehension(c, CHILD(n, 1));
+ if (!comps)
+ return NULL;
+
+ if (type == COMP_GENEXP)
+ return GeneratorExp(elt, comps, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ else if (type == COMP_LISTCOMP)
+ return ListComp(elt, comps, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ else if (type == COMP_SETCOMP)
+ return SetComp(elt, comps, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ else
+ /* Should never happen */
+ return NULL;
+}
+
+/* Fills in the key, value pair corresponding to the dict element. In case
+ * of an unpacking, key is NULL. *i is advanced by the number of ast
+ * elements. Iff successful, nonzero is returned.
+ */
+static int
+ast_for_dictelement(struct compiling *c, const node *n, int *i,
+ expr_ty *key, expr_ty *value)
+{
+ expr_ty expression;
+ if (TYPE(CHILD(n, *i)) == DOUBLESTAR) {
+ assert(NCH(n) - *i >= 2);
+
+ expression = ast_for_expr(c, CHILD(n, *i + 1));
+ if (!expression)
+ return 0;
+ *key = NULL;
+ *value = expression;
+
+ *i += 2;
+ }
+ else {
+ assert(NCH(n) - *i >= 3);
+
+ expression = ast_for_expr(c, CHILD(n, *i));
+ if (!expression)
+ return 0;
+ *key = expression;
+
+ REQ(CHILD(n, *i + 1), COLON);
+
+ expression = ast_for_expr(c, CHILD(n, *i + 2));
+ if (!expression)
+ return 0;
+ *value = expression;
+
+ *i += 3;
+ }
+ return 1;
+}
+
+static expr_ty
+ast_for_dictcomp(struct compiling *c, const node *n)
+{
+ expr_ty key, value;
+ asdl_seq *comps;
+ int i = 0;
+
+ if (!ast_for_dictelement(c, n, &i, &key, &value))
+ return NULL;
+ assert(key);
+ assert(NCH(n) - i >= 1);
+
+ comps = ast_for_comprehension(c, CHILD(n, i));
+ if (!comps)
+ return NULL;
+
+ return DictComp(key, value, comps, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+}
+
+static expr_ty
+ast_for_dictdisplay(struct compiling *c, const node *n)
+{
+ int i;
+ int j;
+ int size;
+ asdl_seq *keys, *values;
+
+ size = (NCH(n) + 1) / 3; /* +1 in case no trailing comma */
+ keys = _Py_asdl_seq_new(size, c->c_arena);
+ if (!keys)
+ return NULL;
+
+ values = _Py_asdl_seq_new(size, c->c_arena);
+ if (!values)
+ return NULL;
+
+ j = 0;
+ for (i = 0; i < NCH(n); i++) {
+ expr_ty key, value;
+
+ if (!ast_for_dictelement(c, n, &i, &key, &value))
+ return NULL;
+ asdl_seq_SET(keys, j, key);
+ asdl_seq_SET(values, j, value);
+
+ j++;
+ }
+ keys->size = j;
+ values->size = j;
+ return Dict(keys, values, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+}
+
+static expr_ty
+ast_for_genexp(struct compiling *c, const node *n)
+{
+ assert(TYPE(n) == (testlist_comp) || TYPE(n) == (argument));
+ return ast_for_itercomp(c, n, COMP_GENEXP);
+}
+
+static expr_ty
+ast_for_listcomp(struct compiling *c, const node *n)
+{
+ assert(TYPE(n) == (testlist_comp));
+ return ast_for_itercomp(c, n, COMP_LISTCOMP);
+}
+
+static expr_ty
+ast_for_setcomp(struct compiling *c, const node *n)
+{
+ assert(TYPE(n) == (dictorsetmaker));
+ return ast_for_itercomp(c, n, COMP_SETCOMP);
+}
+
+static expr_ty
+ast_for_setdisplay(struct compiling *c, const node *n)
+{
+ int i;
+ int size;
+ asdl_seq *elts;
+
+ assert(TYPE(n) == (dictorsetmaker));
+ size = (NCH(n) + 1) / 2; /* +1 in case no trailing comma */
+ elts = _Py_asdl_seq_new(size, c->c_arena);
+ if (!elts)
+ return NULL;
+ for (i = 0; i < NCH(n); i += 2) {
+ expr_ty expression;
+ expression = ast_for_expr(c, CHILD(n, i));
+ if (!expression)
+ return NULL;
+ asdl_seq_SET(elts, i / 2, expression);
+ }
+ return Set(elts, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+}
+
+static expr_ty
+ast_for_atom(struct compiling *c, const node *n)
+{
+ /* atom: '(' [yield_expr|testlist_comp] ')' | '[' [testlist_comp] ']'
+ | '{' [dictmaker|testlist_comp] '}' | NAME | NUMBER | STRING+
+ | '...' | 'None' | 'True' | 'False'
+ */
+ node *ch = CHILD(n, 0);
+
+ switch (TYPE(ch)) {
+ case NAME: {
+ PyObject *name;
+ const char *s = STR(ch);
+ size_t len = strlen(s);
+ if (len >= 4 && len <= 5) {
+ if (!strcmp(s, "None"))
+ return Constant(Py_None, NULL, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ if (!strcmp(s, "True"))
+ return Constant(Py_True, NULL, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ if (!strcmp(s, "False"))
+ return Constant(Py_False, NULL, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+ name = new_identifier(s, c);
+ if (!name)
+ return NULL;
+ /* All names start in Load context, but may later be changed. */
+ return Name(name, Load, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+ case STRING: {
+ expr_ty str = parsestrplus(c, n);
+ if (!str) {
+ const char *errtype = NULL;
+ if (PyErr_ExceptionMatches(PyExc_UnicodeError))
+ errtype = "unicode error";
+ else if (PyErr_ExceptionMatches(PyExc_ValueError))
+ errtype = "value error";
+ if (errtype) {
+ PyObject *type, *value, *tback, *errstr;
+ PyErr_Fetch(&type, &value, &tback);
+ errstr = PyObject_Str(value);
+ if (errstr) {
+ ast_error(c, n, "(%s) %U", errtype, errstr);
+ Py_DECREF(errstr);
+ }
+ else {
+ PyErr_Clear();
+ ast_error(c, n, "(%s) unknown error", errtype);
+ }
+ Py_DECREF(type);
+ Py_XDECREF(value);
+ Py_XDECREF(tback);
+ }
+ return NULL;
+ }
+ return str;
+ }
+ case NUMBER: {
+ PyObject *pynum;
+ /* Underscores in numeric literals are only allowed in Python 3.6 or greater */
+ /* Check for underscores here rather than in parse_number so we can report a line number on error */
+ if (c->c_feature_version < 6 && strchr(STR(ch), '_') != NULL) {
+ ast_error(c, ch,
+ "Underscores in numeric literals are only supported in Python 3.6 and greater");
+ return NULL;
+ }
+ pynum = parsenumber(c, STR(ch));
+ if (!pynum)
+ return NULL;
+
+ if (PyArena_AddPyObject(c->c_arena, pynum) < 0) {
+ Py_DECREF(pynum);
+ return NULL;
+ }
+ return Constant(pynum, NULL, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+ case ELLIPSIS: /* Ellipsis */
+ return Constant(Py_Ellipsis, NULL, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ case LPAR: /* some parenthesized expressions */
+ ch = CHILD(n, 1);
+
+ if (TYPE(ch) == RPAR)
+ return Tuple(NULL, Load, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+
+ if (TYPE(ch) == yield_expr)
+ return ast_for_expr(c, ch);
+
+ /* testlist_comp: test ( comp_for | (',' test)* [','] ) */
+ if (NCH(ch) == 1) {
+ return ast_for_testlist(c, ch);
+ }
+
+ if (TYPE(CHILD(ch, 1)) == comp_for) {
+ return copy_location(ast_for_genexp(c, ch), n, n);
+ }
+ else {
+ return copy_location(ast_for_testlist(c, ch), n, n);
+ }
+ case LSQB: /* list (or list comprehension) */
+ ch = CHILD(n, 1);
+
+ if (TYPE(ch) == RSQB)
+ return List(NULL, Load, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+
+ REQ(ch, testlist_comp);
+ if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) {
+ asdl_seq *elts = seq_for_testlist(c, ch);
+ if (!elts)
+ return NULL;
+
+ return List(elts, Load, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+ else {
+ return copy_location(ast_for_listcomp(c, ch), n, n);
+ }
+ case LBRACE: {
+ /* dictorsetmaker: ( ((test ':' test | '**' test)
+ * (comp_for | (',' (test ':' test | '**' test))* [','])) |
+ * ((test | '*' test)
+ * (comp_for | (',' (test | '*' test))* [','])) ) */
+ expr_ty res;
+ ch = CHILD(n, 1);
+ if (TYPE(ch) == RBRACE) {
+ /* It's an empty dict. */
+ return Dict(NULL, NULL, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+ else {
+ int is_dict = (TYPE(CHILD(ch, 0)) == DOUBLESTAR);
+ if (NCH(ch) == 1 ||
+ (NCH(ch) > 1 &&
+ TYPE(CHILD(ch, 1)) == COMMA)) {
+ /* It's a set display. */
+ res = ast_for_setdisplay(c, ch);
+ }
+ else if (NCH(ch) > 1 &&
+ TYPE(CHILD(ch, 1)) == comp_for) {
+ /* It's a set comprehension. */
+ res = ast_for_setcomp(c, ch);
+ }
+ else if (NCH(ch) > 3 - is_dict &&
+ TYPE(CHILD(ch, 3 - is_dict)) == comp_for) {
+ /* It's a dictionary comprehension. */
+ if (is_dict) {
+ ast_error(c, n,
+ "dict unpacking cannot be used in dict comprehension");
+ return NULL;
+ }
+ res = ast_for_dictcomp(c, ch);
+ }
+ else {
+ /* It's a dictionary display. */
+ res = ast_for_dictdisplay(c, ch);
+ }
+ return copy_location(res, n, n);
+ }
+ }
+ default:
+ PyErr_Format(PyExc_SystemError, "unhandled atom %d", TYPE(ch));
+ return NULL;
+ }
+}
+
+static expr_ty
+ast_for_slice(struct compiling *c, const node *n)
+{
+ node *ch;
+ expr_ty lower = NULL, upper = NULL, step = NULL;
+
+ REQ(n, subscript);
+
+ /*
+ subscript: test | [test] ':' [test] [sliceop]
+ sliceop: ':' [test]
+ */
+ ch = CHILD(n, 0);
+ if (NCH(n) == 1 && TYPE(ch) == test) {
+ return ast_for_expr(c, ch);
+ }
+
+ if (TYPE(ch) == test) {
+ lower = ast_for_expr(c, ch);
+ if (!lower)
+ return NULL;
+ }
+
+ /* If there's an upper bound it's in the second or third position. */
+ if (TYPE(ch) == COLON) {
+ if (NCH(n) > 1) {
+ node *n2 = CHILD(n, 1);
+
+ if (TYPE(n2) == test) {
+ upper = ast_for_expr(c, n2);
+ if (!upper)
+ return NULL;
+ }
+ }
+ } else if (NCH(n) > 2) {
+ node *n2 = CHILD(n, 2);
+
+ if (TYPE(n2) == test) {
+ upper = ast_for_expr(c, n2);
+ if (!upper)
+ return NULL;
+ }
+ }
+
+ ch = CHILD(n, NCH(n) - 1);
+ if (TYPE(ch) == sliceop) {
+ if (NCH(ch) != 1) {
+ ch = CHILD(ch, 1);
+ if (TYPE(ch) == test) {
+ step = ast_for_expr(c, ch);
+ if (!step)
+ return NULL;
+ }
+ }
+ }
+
+ return Slice(lower, upper, step, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+}
+
+static expr_ty
+ast_for_binop(struct compiling *c, const node *n)
+{
+ /* Must account for a sequence of expressions.
+ How should A op B op C by represented?
+ BinOp(BinOp(A, op, B), op, C).
+ */
+
+ int i, nops;
+ expr_ty expr1, expr2, result;
+ operator_ty newoperator;
+
+ expr1 = ast_for_expr(c, CHILD(n, 0));
+ if (!expr1)
+ return NULL;
+
+ expr2 = ast_for_expr(c, CHILD(n, 2));
+ if (!expr2)
+ return NULL;
+
+ newoperator = get_operator(c, CHILD(n, 1));
+ if (!newoperator)
+ return NULL;
+
+ result = BinOp(expr1, newoperator, expr2, LINENO(n), n->n_col_offset,
+ CHILD(n, 2)->n_end_lineno, CHILD(n, 2)->n_end_col_offset,
+ c->c_arena);
+ if (!result)
+ return NULL;
+
+ nops = (NCH(n) - 1) / 2;
+ for (i = 1; i < nops; i++) {
+ expr_ty tmp_result, tmp;
+ const node* next_oper = CHILD(n, i * 2 + 1);
+
+ newoperator = get_operator(c, next_oper);
+ if (!newoperator)
+ return NULL;
+
+ tmp = ast_for_expr(c, CHILD(n, i * 2 + 2));
+ if (!tmp)
+ return NULL;
+
+ tmp_result = BinOp(result, newoperator, tmp,
+ LINENO(n), n->n_col_offset,
+ CHILD(n, i * 2 + 2)->n_end_lineno,
+ CHILD(n, i * 2 + 2)->n_end_col_offset,
+ c->c_arena);
+ if (!tmp_result)
+ return NULL;
+ result = tmp_result;
+ }
+ return result;
+}
+
+static expr_ty
+ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr, const node *start)
+{
+ /* trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
+ subscriptlist: subscript (',' subscript)* [',']
+ subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]
+ */
+ const node *n_copy = n;
+ REQ(n, trailer);
+ if (TYPE(CHILD(n, 0)) == LPAR) {
+ if (NCH(n) == 2)
+ return Call(left_expr, NULL, NULL, LINENO(start), start->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ else
+ return ast_for_call(c, CHILD(n, 1), left_expr,
+ start, CHILD(n, 0), CHILD(n, 2));
+ }
+ else if (TYPE(CHILD(n, 0)) == DOT) {
+ PyObject *attr_id = NEW_IDENTIFIER(CHILD(n, 1));
+ if (!attr_id)
+ return NULL;
+ return Attribute(left_expr, attr_id, Load,
+ LINENO(start), start->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+ else {
+ REQ(CHILD(n, 0), LSQB);
+ REQ(CHILD(n, 2), RSQB);
+ n = CHILD(n, 1);
+ if (NCH(n) == 1) {
+ expr_ty slc = ast_for_slice(c, CHILD(n, 0));
+ if (!slc)
+ return NULL;
+ return Subscript(left_expr, slc, Load, LINENO(start), start->n_col_offset,
+ n_copy->n_end_lineno, n_copy->n_end_col_offset,
+ c->c_arena);
+ }
+ else {
+ int j;
+ expr_ty slc, e;
+ asdl_seq *elts;
+ elts = _Py_asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
+ if (!elts)
+ return NULL;
+ for (j = 0; j < NCH(n); j += 2) {
+ slc = ast_for_slice(c, CHILD(n, j));
+ if (!slc)
+ return NULL;
+ asdl_seq_SET(elts, j / 2, slc);
+ }
+ e = Tuple(elts, Load, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset,
+ c->c_arena);
+ if (!e)
+ return NULL;
+ return Subscript(left_expr, e,
+ Load, LINENO(start), start->n_col_offset,
+ n_copy->n_end_lineno, n_copy->n_end_col_offset,
+ c->c_arena);
+ }
+ }
+}
+
+static expr_ty
+ast_for_factor(struct compiling *c, const node *n)
+{
+ expr_ty expression;
+
+ expression = ast_for_expr(c, CHILD(n, 1));
+ if (!expression)
+ return NULL;
+
+ switch (TYPE(CHILD(n, 0))) {
+ case PLUS:
+ return UnaryOp(UAdd, expression, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset,
+ c->c_arena);
+ case MINUS:
+ return UnaryOp(USub, expression, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset,
+ c->c_arena);
+ case TILDE:
+ return UnaryOp(Invert, expression, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset,
+ c->c_arena);
+ }
+ PyErr_Format(PyExc_SystemError, "unhandled factor: %d",
+ TYPE(CHILD(n, 0)));
+ return NULL;
+}
+
+static expr_ty
+ast_for_atom_expr(struct compiling *c, const node *n)
+{
+ int i, nch, start = 0;
+ expr_ty e;
+
+ REQ(n, atom_expr);
+ nch = NCH(n);
+
+ if (TYPE(CHILD(n, 0)) == AWAIT) {
+ if (c->c_feature_version < 5) {
+ ast_error(c, n,
+ "Await expressions are only supported in Python 3.5 and greater");
+ return NULL;
+ }
+ start = 1;
+ assert(nch > 1);
+ }
+
+ e = ast_for_atom(c, CHILD(n, start));
+ if (!e)
+ return NULL;
+ if (nch == 1)
+ return e;
+ if (start && nch == 2) {
+ return Await(e, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+
+ for (i = start + 1; i < nch; i++) {
+ node *ch = CHILD(n, i);
+ if (TYPE(ch) != trailer)
+ break;
+ e = ast_for_trailer(c, ch, e, CHILD(n, start));
+ if (!e)
+ return NULL;
+ }
+
+ if (start) {
+ /* there was an 'await' */
+ return Await(e, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+ else {
+ return e;
+ }
+}
+
+static expr_ty
+ast_for_power(struct compiling *c, const node *n)
+{
+ /* power: atom trailer* ('**' factor)*
+ */
+ expr_ty e;
+ REQ(n, power);
+ e = ast_for_atom_expr(c, CHILD(n, 0));
+ if (!e)
+ return NULL;
+ if (NCH(n) == 1)
+ return e;
+ if (TYPE(CHILD(n, NCH(n) - 1)) == factor) {
+ expr_ty f = ast_for_expr(c, CHILD(n, NCH(n) - 1));
+ if (!f)
+ return NULL;
+ e = BinOp(e, Pow, f, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+ return e;
+}
+
+static expr_ty
+ast_for_starred(struct compiling *c, const node *n)
+{
+ expr_ty tmp;
+ REQ(n, star_expr);
+
+ tmp = ast_for_expr(c, CHILD(n, 1));
+ if (!tmp)
+ return NULL;
+
+ /* The Load context is changed later. */
+ return Starred(tmp, Load, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+}
+
+
+/* Do not name a variable 'expr'! Will cause a compile error.
+*/
+
+static expr_ty
+ast_for_expr(struct compiling *c, const node *n)
+{
+ /* handle the full range of simple expressions
+ namedexpr_test: test [':=' test]
+ test: or_test ['if' or_test 'else' test] | lambdef
+ test_nocond: or_test | lambdef_nocond
+ or_test: and_test ('or' and_test)*
+ and_test: not_test ('and' not_test)*
+ not_test: 'not' not_test | comparison
+ comparison: expr (comp_op expr)*
+ expr: xor_expr ('|' xor_expr)*
+ xor_expr: and_expr ('^' and_expr)*
+ and_expr: shift_expr ('&' shift_expr)*
+ shift_expr: arith_expr (('<<'|'>>') arith_expr)*
+ arith_expr: term (('+'|'-') term)*
+ term: factor (('*'|'@'|'/'|'%'|'//') factor)*
+ factor: ('+'|'-'|'~') factor | power
+ power: atom_expr ['**' factor]
+ atom_expr: [AWAIT] atom trailer*
+ yield_expr: 'yield' [yield_arg]
+ */
+
+ asdl_seq *seq;
+ int i;
+
+ loop:
+ switch (TYPE(n)) {
+ case namedexpr_test:
+ if (NCH(n) == 3)
+ return ast_for_namedexpr(c, n);
+ /* Fallthrough */
+ case test:
+ case test_nocond:
+ if (TYPE(CHILD(n, 0)) == lambdef ||
+ TYPE(CHILD(n, 0)) == lambdef_nocond)
+ return ast_for_lambdef(c, CHILD(n, 0));
+ else if (NCH(n) > 1)
+ return ast_for_ifexpr(c, n);
+ /* Fallthrough */
+ case or_test:
+ case and_test:
+ if (NCH(n) == 1) {
+ n = CHILD(n, 0);
+ goto loop;
+ }
+ seq = _Py_asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
+ if (!seq)
+ return NULL;
+ for (i = 0; i < NCH(n); i += 2) {
+ expr_ty e = ast_for_expr(c, CHILD(n, i));
+ if (!e)
+ return NULL;
+ asdl_seq_SET(seq, i / 2, e);
+ }
+ if (!strcmp(STR(CHILD(n, 1)), "and"))
+ return BoolOp(And, seq, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset,
+ c->c_arena);
+ assert(!strcmp(STR(CHILD(n, 1)), "or"));
+ return BoolOp(Or, seq, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ case not_test:
+ if (NCH(n) == 1) {
+ n = CHILD(n, 0);
+ goto loop;
+ }
+ else {
+ expr_ty expression = ast_for_expr(c, CHILD(n, 1));
+ if (!expression)
+ return NULL;
+
+ return UnaryOp(Not, expression, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset,
+ c->c_arena);
+ }
+ case comparison:
+ if (NCH(n) == 1) {
+ n = CHILD(n, 0);
+ goto loop;
+ }
+ else {
+ expr_ty expression;
+ asdl_int_seq *ops;
+ asdl_seq *cmps;
+ ops = _Py_asdl_int_seq_new(NCH(n) / 2, c->c_arena);
+ if (!ops)
+ return NULL;
+ cmps = _Py_asdl_seq_new(NCH(n) / 2, c->c_arena);
+ if (!cmps) {
+ return NULL;
+ }
+ for (i = 1; i < NCH(n); i += 2) {
+ cmpop_ty newoperator;
+
+ newoperator = ast_for_comp_op(c, CHILD(n, i));
+ if (!newoperator) {
+ return NULL;
+ }
+
+ expression = ast_for_expr(c, CHILD(n, i + 1));
+ if (!expression) {
+ return NULL;
+ }
+
+ asdl_seq_SET(ops, i / 2, newoperator);
+ asdl_seq_SET(cmps, i / 2, expression);
+ }
+ expression = ast_for_expr(c, CHILD(n, 0));
+ if (!expression) {
+ return NULL;
+ }
+
+ return Compare(expression, ops, cmps, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+
+ case star_expr:
+ return ast_for_starred(c, n);
+ /* The next five cases all handle BinOps. The main body of code
+ is the same in each case, but the switch turned inside out to
+ reuse the code for each type of operator.
+ */
+ case expr:
+ case xor_expr:
+ case and_expr:
+ case shift_expr:
+ case arith_expr:
+ case term:
+ if (NCH(n) == 1) {
+ n = CHILD(n, 0);
+ goto loop;
+ }
+ return ast_for_binop(c, n);
+ case yield_expr: {
+ node *an = NULL;
+ node *en = NULL;
+ int is_from = 0;
+ expr_ty exp = NULL;
+ if (NCH(n) > 1)
+ an = CHILD(n, 1); /* yield_arg */
+ if (an) {
+ en = CHILD(an, NCH(an) - 1);
+ if (NCH(an) == 2) {
+ is_from = 1;
+ exp = ast_for_expr(c, en);
+ }
+ else
+ exp = ast_for_testlist(c, en);
+ if (!exp)
+ return NULL;
+ }
+ if (is_from)
+ return YieldFrom(exp, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ return Yield(exp, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+ case factor:
+ if (NCH(n) == 1) {
+ n = CHILD(n, 0);
+ goto loop;
+ }
+ return ast_for_factor(c, n);
+ case power:
+ return ast_for_power(c, n);
+ default:
+ PyErr_Format(PyExc_SystemError, "unhandled expr: %d", TYPE(n));
+ return NULL;
+ }
+ /* should never get here unless if error is set */
+ return NULL;
+}
+
+static expr_ty
+ast_for_call(struct compiling *c, const node *n, expr_ty func,
+ const node *start, const node *maybegenbeg, const node *closepar)
+{
+ /*
+ arglist: argument (',' argument)* [',']
+ argument: ( test [comp_for] | '*' test | test '=' test | '**' test )
+ */
+
+ int i, nargs, nkeywords;
+ int ndoublestars;
+ asdl_seq *args;
+ asdl_seq *keywords;
+
+ REQ(n, arglist);
+
+ nargs = 0;
+ nkeywords = 0;
+ for (i = 0; i < NCH(n); i++) {
+ node *ch = CHILD(n, i);
+ if (TYPE(ch) == argument) {
+ if (NCH(ch) == 1)
+ nargs++;
+ else if (TYPE(CHILD(ch, 1)) == comp_for) {
+ nargs++;
+ if (!maybegenbeg) {
+ ast_error(c, ch, "invalid syntax");
+ return NULL;
+ }
+ if (NCH(n) > 1) {
+ ast_error(c, ch, "Generator expression must be parenthesized");
+ return NULL;
+ }
+ }
+ else if (TYPE(CHILD(ch, 0)) == STAR)
+ nargs++;
+ else if (TYPE(CHILD(ch, 1)) == COLONEQUAL) {
+ nargs++;
+ }
+ else
+ /* TYPE(CHILD(ch, 0)) == DOUBLESTAR or keyword argument */
+ nkeywords++;
+ }
+ }
+
+ args = _Py_asdl_seq_new(nargs, c->c_arena);
+ if (!args)
+ return NULL;
+ keywords = _Py_asdl_seq_new(nkeywords, c->c_arena);
+ if (!keywords)
+ return NULL;
+
+ nargs = 0; /* positional arguments + iterable argument unpackings */
+ nkeywords = 0; /* keyword arguments + keyword argument unpackings */
+ ndoublestars = 0; /* just keyword argument unpackings */
+ for (i = 0; i < NCH(n); i++) {
+ node *ch = CHILD(n, i);
+ if (TYPE(ch) == argument) {
+ expr_ty e;
+ node *chch = CHILD(ch, 0);
+ if (NCH(ch) == 1) {
+ /* a positional argument */
+ if (nkeywords) {
+ if (ndoublestars) {
+ ast_error(c, chch,
+ "positional argument follows "
+ "keyword argument unpacking");
+ }
+ else {
+ ast_error(c, chch,
+ "positional argument follows "
+ "keyword argument");
+ }
+ return NULL;
+ }
+ e = ast_for_expr(c, chch);
+ if (!e)
+ return NULL;
+ asdl_seq_SET(args, nargs++, e);
+ }
+ else if (TYPE(chch) == STAR) {
+ /* an iterable argument unpacking */
+ expr_ty starred;
+ if (ndoublestars) {
+ ast_error(c, chch,
+ "iterable argument unpacking follows "
+ "keyword argument unpacking");
+ return NULL;
+ }
+ e = ast_for_expr(c, CHILD(ch, 1));
+ if (!e)
+ return NULL;
+ starred = Starred(e, Load, LINENO(chch),
+ chch->n_col_offset,
+ e->end_lineno, e->end_col_offset,
+ c->c_arena);
+ if (!starred)
+ return NULL;
+ asdl_seq_SET(args, nargs++, starred);
+
+ }
+ else if (TYPE(chch) == DOUBLESTAR) {
+ /* a keyword argument unpacking */
+ keyword_ty kw;
+ i++;
+ e = ast_for_expr(c, CHILD(ch, 1));
+ if (!e)
+ return NULL;
+ kw = keyword(NULL, e, chch->n_lineno, chch->n_col_offset,
+ e->end_lineno, e->end_col_offset, c->c_arena);
+ asdl_seq_SET(keywords, nkeywords++, kw);
+ ndoublestars++;
+ }
+ else if (TYPE(CHILD(ch, 1)) == comp_for) {
+ /* the lone generator expression */
+ e = copy_location(ast_for_genexp(c, ch), maybegenbeg, closepar);
+ if (!e)
+ return NULL;
+ asdl_seq_SET(args, nargs++, e);
+ }
+ else if (TYPE(CHILD(ch, 1)) == COLONEQUAL) {
+ /* treat colon equal as positional argument */
+ if (nkeywords) {
+ if (ndoublestars) {
+ ast_error(c, chch,
+ "positional argument follows "
+ "keyword argument unpacking");
+ }
+ else {
+ ast_error(c, chch,
+ "positional argument follows "
+ "keyword argument");
+ }
+ return NULL;
+ }
+ e = ast_for_namedexpr(c, ch);
+ if (!e)
+ return NULL;
+ asdl_seq_SET(args, nargs++, e);
+ }
+ else {
+ /* a keyword argument */
+ keyword_ty kw;
+ identifier key;
+
+ // To remain LL(1), the grammar accepts any test (basically, any
+ // expression) in the keyword slot of a call site. So, we need
+ // to manually enforce that the keyword is a NAME here.
+ static const int name_tree[] = {
+ test,
+ or_test,
+ and_test,
+ not_test,
+ comparison,
+ expr,
+ xor_expr,
+ and_expr,
+ shift_expr,
+ arith_expr,
+ term,
+ factor,
+ power,
+ atom_expr,
+ atom,
+ 0,
+ };
+ node *expr_node = chch;
+ for (int i = 0; name_tree[i]; i++) {
+ if (TYPE(expr_node) != name_tree[i])
+ break;
+ if (NCH(expr_node) != 1)
+ break;
+ expr_node = CHILD(expr_node, 0);
+ }
+ if (TYPE(expr_node) != NAME) {
+ ast_error(c, chch,
+ "expression cannot contain assignment, "
+ "perhaps you meant \"==\"?");
+ return NULL;
+ }
+ key = new_identifier(STR(expr_node), c);
+ if (key == NULL) {
+ return NULL;
+ }
+ if (forbidden_name(c, key, chch, 1)) {
+ return NULL;
+ }
+ e = ast_for_expr(c, CHILD(ch, 2));
+ if (!e)
+ return NULL;
+ kw = keyword(key, e, chch->n_lineno, chch->n_col_offset,
+ e->end_lineno, e->end_col_offset, c->c_arena);
+
+ if (!kw)
+ return NULL;
+ asdl_seq_SET(keywords, nkeywords++, kw);
+ }
+ }
+ }
+
+ return Call(func, args, keywords, LINENO(start), start->n_col_offset,
+ closepar->n_end_lineno, closepar->n_end_col_offset, c->c_arena);
+}
+
+static expr_ty
+ast_for_testlist(struct compiling *c, const node* n)
+{
+ /* testlist_comp: test (comp_for | (',' test)* [',']) */
+ /* testlist: test (',' test)* [','] */
+ assert(NCH(n) > 0);
+ if (TYPE(n) == testlist_comp) {
+ if (NCH(n) > 1)
+ assert(TYPE(CHILD(n, 1)) != comp_for);
+ }
+ else {
+ assert(TYPE(n) == testlist ||
+ TYPE(n) == testlist_star_expr);
+ }
+ if (NCH(n) == 1)
+ return ast_for_expr(c, CHILD(n, 0));
+ else {
+ asdl_seq *tmp = seq_for_testlist(c, n);
+ if (!tmp)
+ return NULL;
+ return Tuple(tmp, Load, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+}
+
+static stmt_ty
+ast_for_expr_stmt(struct compiling *c, const node *n)
+{
+ REQ(n, expr_stmt);
+ /* expr_stmt: testlist_star_expr (annassign | augassign (yield_expr|testlist) |
+ [('=' (yield_expr|testlist_star_expr))+ [TYPE_COMMENT]] )
+ annassign: ':' test ['=' (yield_expr|testlist)]
+ testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
+ augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' |
+ '<<=' | '>>=' | '**=' | '//=')
+ test: ... here starts the operator precedence dance
+ */
+ int num = NCH(n);
+
+ if (num == 1) {
+ expr_ty e = ast_for_testlist(c, CHILD(n, 0));
+ if (!e)
+ return NULL;
+
+ return Expr(e, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+ else if (TYPE(CHILD(n, 1)) == augassign) {
+ expr_ty expr1, expr2;
+ operator_ty newoperator;
+ node *ch = CHILD(n, 0);
+
+ expr1 = ast_for_testlist(c, ch);
+ if (!expr1)
+ return NULL;
+ /* Augmented assignments can only have a name, a subscript, or an
+ attribute on the left, though, so we have to explicitly check for
+ those. */
+ switch (expr1->kind) {
+ case Name_kind:
+ case Attribute_kind:
+ case Subscript_kind:
+ break;
+ default:
+ ast_error(c, ch, "'%s' is an illegal expression for augmented assignment",
+ get_expr_name(expr1));
+ return NULL;
+ }
+
+ /* set_context checks that most expressions are not the left side. */
+ if(!set_context(c, expr1, Store, ch)) {
+ return NULL;
+ }
+
+ ch = CHILD(n, 2);
+ if (TYPE(ch) == testlist)
+ expr2 = ast_for_testlist(c, ch);
+ else
+ expr2 = ast_for_expr(c, ch);
+ if (!expr2)
+ return NULL;
+
+ newoperator = ast_for_augassign(c, CHILD(n, 1));
+ if (!newoperator)
+ return NULL;
+
+ return AugAssign(expr1, newoperator, expr2, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+ else if (TYPE(CHILD(n, 1)) == annassign) {
+ expr_ty expr1, expr2, expr3;
+ node *ch = CHILD(n, 0);
+ node *deep, *ann = CHILD(n, 1);
+ int simple = 1;
+
+ /* AnnAssigns are only allowed in Python 3.6 or greater */
+ if (c->c_feature_version < 6) {
+ ast_error(c, ch,
+ "Variable annotation syntax is only supported in Python 3.6 and greater");
+ return NULL;
+ }
+
+ /* we keep track of parens to qualify (x) as expression not name */
+ deep = ch;
+ while (NCH(deep) == 1) {
+ deep = CHILD(deep, 0);
+ }
+ if (NCH(deep) > 0 && TYPE(CHILD(deep, 0)) == LPAR) {
+ simple = 0;
+ }
+ expr1 = ast_for_testlist(c, ch);
+ if (!expr1) {
+ return NULL;
+ }
+ switch (expr1->kind) {
+ case Name_kind:
+ if (forbidden_name(c, expr1->v.Name.id, n, 0)) {
+ return NULL;
+ }
+ expr1->v.Name.ctx = Store;
+ break;
+ case Attribute_kind:
+ if (forbidden_name(c, expr1->v.Attribute.attr, n, 1)) {
+ return NULL;
+ }
+ expr1->v.Attribute.ctx = Store;
+ break;
+ case Subscript_kind:
+ expr1->v.Subscript.ctx = Store;
+ break;
+ case List_kind:
+ ast_error(c, ch,
+ "only single target (not list) can be annotated");
+ return NULL;
+ case Tuple_kind:
+ ast_error(c, ch,
+ "only single target (not tuple) can be annotated");
+ return NULL;
+ default:
+ ast_error(c, ch,
+ "illegal target for annotation");
+ return NULL;
+ }
+
+ if (expr1->kind != Name_kind) {
+ simple = 0;
+ }
+ ch = CHILD(ann, 1);
+ expr2 = ast_for_expr(c, ch);
+ if (!expr2) {
+ return NULL;
+ }
+ if (NCH(ann) == 2) {
+ return AnnAssign(expr1, expr2, NULL, simple,
+ LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+ else {
+ ch = CHILD(ann, 3);
+ if (TYPE(ch) == testlist_star_expr) {
+ expr3 = ast_for_testlist(c, ch);
+ }
+ else {
+ expr3 = ast_for_expr(c, ch);
+ }
+ if (!expr3) {
+ return NULL;
+ }
+ return AnnAssign(expr1, expr2, expr3, simple,
+ LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+ }
+ else {
+ int i, nch_minus_type, has_type_comment;
+ asdl_seq *targets;
+ node *value;
+ expr_ty expression;
+ string type_comment;
+
+ /* a normal assignment */
+ REQ(CHILD(n, 1), EQUAL);
+
+ has_type_comment = TYPE(CHILD(n, num - 1)) == TYPE_COMMENT;
+ nch_minus_type = num - has_type_comment;
+
+ targets = _Py_asdl_seq_new(nch_minus_type / 2, c->c_arena);
+ if (!targets)
+ return NULL;
+ for (i = 0; i < nch_minus_type - 2; i += 2) {
+ expr_ty e;
+ node *ch = CHILD(n, i);
+ if (TYPE(ch) == yield_expr) {
+ ast_error(c, ch, "assignment to yield expression not possible");
+ return NULL;
+ }
+ e = ast_for_testlist(c, ch);
+ if (!e)
+ return NULL;
+
+ /* set context to assign */
+ if (!set_context(c, e, Store, CHILD(n, i)))
+ return NULL;
+
+ asdl_seq_SET(targets, i / 2, e);
+ }
+ value = CHILD(n, nch_minus_type - 1);
+ if (TYPE(value) == testlist_star_expr)
+ expression = ast_for_testlist(c, value);
+ else
+ expression = ast_for_expr(c, value);
+ if (!expression)
+ return NULL;
+ if (has_type_comment) {
+ type_comment = NEW_TYPE_COMMENT(CHILD(n, nch_minus_type));
+ if (!type_comment)
+ return NULL;
+ }
+ else
+ type_comment = NULL;
+ return Assign(targets, expression, type_comment, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+}
+
+
+static asdl_seq *
+ast_for_exprlist(struct compiling *c, const node *n, expr_context_ty context)
+{
+ asdl_seq *seq;
+ int i;
+ expr_ty e;
+
+ REQ(n, exprlist);
+
+ seq = _Py_asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
+ if (!seq)
+ return NULL;
+ for (i = 0; i < NCH(n); i += 2) {
+ e = ast_for_expr(c, CHILD(n, i));
+ if (!e)
+ return NULL;
+ asdl_seq_SET(seq, i / 2, e);
+ if (context && !set_context(c, e, context, CHILD(n, i)))
+ return NULL;
+ }
+ return seq;
+}
+
+static stmt_ty
+ast_for_del_stmt(struct compiling *c, const node *n)
+{
+ asdl_seq *expr_list;
+
+ /* del_stmt: 'del' exprlist */
+ REQ(n, del_stmt);
+
+ expr_list = ast_for_exprlist(c, CHILD(n, 1), Del);
+ if (!expr_list)
+ return NULL;
+ return Delete(expr_list, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+}
+
+static stmt_ty
+ast_for_flow_stmt(struct compiling *c, const node *n)
+{
+ /*
+ flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt
+ | yield_stmt
+ break_stmt: 'break'
+ continue_stmt: 'continue'
+ return_stmt: 'return' [testlist]
+ yield_stmt: yield_expr
+ yield_expr: 'yield' testlist | 'yield' 'from' test
+ raise_stmt: 'raise' [test [',' test [',' test]]]
+ */
+ node *ch;
+
+ REQ(n, flow_stmt);
+ ch = CHILD(n, 0);
+ switch (TYPE(ch)) {
+ case break_stmt:
+ return Break(LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ case continue_stmt:
+ return Continue(LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ case yield_stmt: { /* will reduce to yield_expr */
+ expr_ty exp = ast_for_expr(c, CHILD(ch, 0));
+ if (!exp)
+ return NULL;
+ return Expr(exp, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+ case return_stmt:
+ if (NCH(ch) == 1)
+ return Return(NULL, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ else {
+ expr_ty expression = ast_for_testlist(c, CHILD(ch, 1));
+ if (!expression)
+ return NULL;
+ return Return(expression, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+ case raise_stmt:
+ if (NCH(ch) == 1)
+ return Raise(NULL, NULL, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ else if (NCH(ch) >= 2) {
+ expr_ty cause = NULL;
+ expr_ty expression = ast_for_expr(c, CHILD(ch, 1));
+ if (!expression)
+ return NULL;
+ if (NCH(ch) == 4) {
+ cause = ast_for_expr(c, CHILD(ch, 3));
+ if (!cause)
+ return NULL;
+ }
+ return Raise(expression, cause, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+ /* fall through */
+ default:
+ PyErr_Format(PyExc_SystemError,
+ "unexpected flow_stmt: %d", TYPE(ch));
+ return NULL;
+ }
+}
+
+static alias_ty
+alias_for_import_name(struct compiling *c, const node *n, int store)
+{
+ /*
+ import_as_name: NAME ['as' NAME]
+ dotted_as_name: dotted_name ['as' NAME]
+ dotted_name: NAME ('.' NAME)*
+ */
+ identifier str, name;
+
+ loop:
+ switch (TYPE(n)) {
+ case import_as_name: {
+ node *name_node = CHILD(n, 0);
+ str = NULL;
+ name = NEW_IDENTIFIER(name_node);
+ if (!name)
+ return NULL;
+ if (NCH(n) == 3) {
+ node *str_node = CHILD(n, 2);
+ str = NEW_IDENTIFIER(str_node);
+ if (!str)
+ return NULL;
+ if (store && forbidden_name(c, str, str_node, 0))
+ return NULL;
+ }
+ else {
+ if (forbidden_name(c, name, name_node, 0))
+ return NULL;
+ }
+ return alias(name, str, c->c_arena);
+ }
+ case dotted_as_name:
+ if (NCH(n) == 1) {
+ n = CHILD(n, 0);
+ goto loop;
+ }
+ else {
+ node *asname_node = CHILD(n, 2);
+ alias_ty a = alias_for_import_name(c, CHILD(n, 0), 0);
+ if (!a)
+ return NULL;
+ assert(!a->asname);
+ a->asname = NEW_IDENTIFIER(asname_node);
+ if (!a->asname)
+ return NULL;
+ if (forbidden_name(c, a->asname, asname_node, 0))
+ return NULL;
+ return a;
+ }
+ case dotted_name:
+ if (NCH(n) == 1) {
+ node *name_node = CHILD(n, 0);
+ name = NEW_IDENTIFIER(name_node);
+ if (!name)
+ return NULL;
+ if (store && forbidden_name(c, name, name_node, 0))
+ return NULL;
+ return alias(name, NULL, c->c_arena);
+ }
+ else {
+ /* Create a string of the form "a.b.c" */
+ int i;
+ size_t len;
+ char *s;
+ PyObject *uni;
+
+ len = 0;
+ for (i = 0; i < NCH(n); i += 2)
+ /* length of string plus one for the dot */
+ len += strlen(STR(CHILD(n, i))) + 1;
+ len--; /* the last name doesn't have a dot */
+ str = PyBytes_FromStringAndSize(NULL, len);
+ if (!str)
+ return NULL;
+ s = PyBytes_AS_STRING(str);
+ if (!s)
+ return NULL;
+ for (i = 0; i < NCH(n); i += 2) {
+ char *sch = STR(CHILD(n, i));
+ strcpy(s, STR(CHILD(n, i)));
+ s += strlen(sch);
+ *s++ = '.';
+ }
+ --s;
+ *s = '\0';
+ uni = PyUnicode_DecodeUTF8(PyBytes_AS_STRING(str),
+ PyBytes_GET_SIZE(str),
+ NULL);
+ Py_DECREF(str);
+ if (!uni)
+ return NULL;
+ str = uni;
+ PyUnicode_InternInPlace(&str);
+ if (PyArena_AddPyObject(c->c_arena, str) < 0) {
+ Py_DECREF(str);
+ return NULL;
+ }
+ return alias(str, NULL, c->c_arena);
+ }
+ case STAR:
+ str = PyUnicode_InternFromString("*");
+ if (!str)
+ return NULL;
+ if (PyArena_AddPyObject(c->c_arena, str) < 0) {
+ Py_DECREF(str);
+ return NULL;
+ }
+ return alias(str, NULL, c->c_arena);
+ default:
+ PyErr_Format(PyExc_SystemError,
+ "unexpected import name: %d", TYPE(n));
+ return NULL;
+ }
+}
+
+static stmt_ty
+ast_for_import_stmt(struct compiling *c, const node *n)
+{
+ /*
+ import_stmt: import_name | import_from
+ import_name: 'import' dotted_as_names
+ import_from: 'from' (('.' | '...')* dotted_name | ('.' | '...')+)
+ 'import' ('*' | '(' import_as_names ')' | import_as_names)
+ */
+ int lineno;
+ int col_offset;
+ int i;
+ asdl_seq *aliases;
+
+ REQ(n, import_stmt);
+ lineno = LINENO(n);
+ col_offset = n->n_col_offset;
+ n = CHILD(n, 0);
+ if (TYPE(n) == import_name) {
+ n = CHILD(n, 1);
+ REQ(n, dotted_as_names);
+ aliases = _Py_asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
+ if (!aliases)
+ return NULL;
+ for (i = 0; i < NCH(n); i += 2) {
+ alias_ty import_alias = alias_for_import_name(c, CHILD(n, i), 1);
+ if (!import_alias)
+ return NULL;
+ asdl_seq_SET(aliases, i / 2, import_alias);
+ }
+ // Even though n is modified above, the end position is not changed
+ return Import(aliases, lineno, col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+ else if (TYPE(n) == import_from) {
+ int n_children;
+ int idx, ndots = 0;
+ const node *n_copy = n;
+ alias_ty mod = NULL;
+ identifier modname = NULL;
+
+ /* Count the number of dots (for relative imports) and check for the
+ optional module name */
+ for (idx = 1; idx < NCH(n); idx++) {
+ if (TYPE(CHILD(n, idx)) == dotted_name) {
+ mod = alias_for_import_name(c, CHILD(n, idx), 0);
+ if (!mod)
+ return NULL;
+ idx++;
+ break;
+ } else if (TYPE(CHILD(n, idx)) == ELLIPSIS) {
+ /* three consecutive dots are tokenized as one ELLIPSIS */
+ ndots += 3;
+ continue;
+ } else if (TYPE(CHILD(n, idx)) != DOT) {
+ break;
+ }
+ ndots++;
+ }
+ idx++; /* skip over the 'import' keyword */
+ switch (TYPE(CHILD(n, idx))) {
+ case STAR:
+ /* from ... import * */
+ n = CHILD(n, idx);
+ n_children = 1;
+ break;
+ case LPAR:
+ /* from ... import (x, y, z) */
+ n = CHILD(n, idx + 1);
+ n_children = NCH(n);
+ break;
+ case import_as_names:
+ /* from ... import x, y, z */
+ n = CHILD(n, idx);
+ n_children = NCH(n);
+ if (n_children % 2 == 0) {
+ ast_error(c, n,
+ "trailing comma not allowed without"
+ " surrounding parentheses");
+ return NULL;
+ }
+ break;
+ default:
+ ast_error(c, n, "Unexpected node-type in from-import");
+ return NULL;
+ }
+
+ aliases = _Py_asdl_seq_new((n_children + 1) / 2, c->c_arena);
+ if (!aliases)
+ return NULL;
+
+ /* handle "from ... import *" special b/c there's no children */
+ if (TYPE(n) == STAR) {
+ alias_ty import_alias = alias_for_import_name(c, n, 1);
+ if (!import_alias)
+ return NULL;
+ asdl_seq_SET(aliases, 0, import_alias);
+ }
+ else {
+ for (i = 0; i < NCH(n); i += 2) {
+ alias_ty import_alias = alias_for_import_name(c, CHILD(n, i), 1);
+ if (!import_alias)
+ return NULL;
+ asdl_seq_SET(aliases, i / 2, import_alias);
+ }
+ }
+ if (mod != NULL)
+ modname = mod->name;
+ return ImportFrom(modname, aliases, ndots, lineno, col_offset,
+ n_copy->n_end_lineno, n_copy->n_end_col_offset,
+ c->c_arena);
+ }
+ PyErr_Format(PyExc_SystemError,
+ "unknown import statement: starts with command '%s'",
+ STR(CHILD(n, 0)));
+ return NULL;
+}
+
+static stmt_ty
+ast_for_global_stmt(struct compiling *c, const node *n)
+{
+ /* global_stmt: 'global' NAME (',' NAME)* */
+ identifier name;
+ asdl_seq *s;
+ int i;
+
+ REQ(n, global_stmt);
+ s = _Py_asdl_seq_new(NCH(n) / 2, c->c_arena);
+ if (!s)
+ return NULL;
+ for (i = 1; i < NCH(n); i += 2) {
+ name = NEW_IDENTIFIER(CHILD(n, i));
+ if (!name)
+ return NULL;
+ asdl_seq_SET(s, i / 2, name);
+ }
+ return Global(s, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+}
+
+static stmt_ty
+ast_for_nonlocal_stmt(struct compiling *c, const node *n)
+{
+ /* nonlocal_stmt: 'nonlocal' NAME (',' NAME)* */
+ identifier name;
+ asdl_seq *s;
+ int i;
+
+ REQ(n, nonlocal_stmt);
+ s = _Py_asdl_seq_new(NCH(n) / 2, c->c_arena);
+ if (!s)
+ return NULL;
+ for (i = 1; i < NCH(n); i += 2) {
+ name = NEW_IDENTIFIER(CHILD(n, i));
+ if (!name)
+ return NULL;
+ asdl_seq_SET(s, i / 2, name);
+ }
+ return Nonlocal(s, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+}
+
+static stmt_ty
+ast_for_assert_stmt(struct compiling *c, const node *n)
+{
+ /* assert_stmt: 'assert' test [',' test] */
+ REQ(n, assert_stmt);
+ if (NCH(n) == 2) {
+ expr_ty expression = ast_for_expr(c, CHILD(n, 1));
+ if (!expression)
+ return NULL;
+ return Assert(expression, NULL, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+ else if (NCH(n) == 4) {
+ expr_ty expr1, expr2;
+
+ expr1 = ast_for_expr(c, CHILD(n, 1));
+ if (!expr1)
+ return NULL;
+ expr2 = ast_for_expr(c, CHILD(n, 3));
+ if (!expr2)
+ return NULL;
+
+ return Assert(expr1, expr2, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+ PyErr_Format(PyExc_SystemError,
+ "improper number of parts to 'assert' statement: %d",
+ NCH(n));
+ return NULL;
+}
+
+static asdl_seq *
+ast_for_suite(struct compiling *c, const node *n)
+{
+ /* suite: simple_stmt | NEWLINE [TYPE_COMMENT NEWLINE] INDENT stmt+ DEDENT */
+ asdl_seq *seq;
+ stmt_ty s;
+ int i, total, num, end, pos = 0;
+ node *ch;
+
+ if (TYPE(n) != func_body_suite) {
+ REQ(n, suite);
+ }
+
+ total = num_stmts(n);
+ seq = _Py_asdl_seq_new(total, c->c_arena);
+ if (!seq)
+ return NULL;
+ if (TYPE(CHILD(n, 0)) == simple_stmt) {
+ n = CHILD(n, 0);
+ /* simple_stmt always ends with a NEWLINE,
+ and may have a trailing SEMI
+ */
+ end = NCH(n) - 1;
+ if (TYPE(CHILD(n, end - 1)) == SEMI)
+ end--;
+ /* loop by 2 to skip semi-colons */
+ for (i = 0; i < end; i += 2) {
+ ch = CHILD(n, i);
+ s = ast_for_stmt(c, ch);
+ if (!s)
+ return NULL;
+ asdl_seq_SET(seq, pos++, s);
+ }
+ }
+ else {
+ i = 2;
+ if (TYPE(CHILD(n, 1)) == TYPE_COMMENT) {
+ i += 2;
+ REQ(CHILD(n, 2), NEWLINE);
+ }
+
+ for (; i < (NCH(n) - 1); i++) {
+ ch = CHILD(n, i);
+ REQ(ch, stmt);
+ num = num_stmts(ch);
+ if (num == 1) {
+ /* small_stmt or compound_stmt with only one child */
+ s = ast_for_stmt(c, ch);
+ if (!s)
+ return NULL;
+ asdl_seq_SET(seq, pos++, s);
+ }
+ else {
+ int j;
+ ch = CHILD(ch, 0);
+ REQ(ch, simple_stmt);
+ for (j = 0; j < NCH(ch); j += 2) {
+ /* statement terminates with a semi-colon ';' */
+ if (NCH(CHILD(ch, j)) == 0) {
+ assert((j + 1) == NCH(ch));
+ break;
+ }
+ s = ast_for_stmt(c, CHILD(ch, j));
+ if (!s)
+ return NULL;
+ asdl_seq_SET(seq, pos++, s);
+ }
+ }
+ }
+ }
+ assert(pos == seq->size);
+ return seq;
+}
+
+static void
+get_last_end_pos(asdl_seq *s, int *end_lineno, int *end_col_offset)
+{
+ Py_ssize_t tot = asdl_seq_LEN(s);
+ // There must be no empty suites.
+ assert(tot > 0);
+ stmt_ty last = asdl_seq_GET(s, tot - 1);
+ *end_lineno = last->end_lineno;
+ *end_col_offset = last->end_col_offset;
+}
+
+static stmt_ty
+ast_for_if_stmt(struct compiling *c, const node *n)
+{
+ /* if_stmt: 'if' test ':' suite ('elif' test ':' suite)*
+ ['else' ':' suite]
+ */
+ char *s;
+ int end_lineno, end_col_offset;
+
+ REQ(n, if_stmt);
+
+ if (NCH(n) == 4) {
+ expr_ty expression;
+ asdl_seq *suite_seq;
+
+ expression = ast_for_expr(c, CHILD(n, 1));
+ if (!expression)
+ return NULL;
+ suite_seq = ast_for_suite(c, CHILD(n, 3));
+ if (!suite_seq)
+ return NULL;
+ get_last_end_pos(suite_seq, &end_lineno, &end_col_offset);
+
+ return If(expression, suite_seq, NULL, LINENO(n), n->n_col_offset,
+ end_lineno, end_col_offset, c->c_arena);
+ }
+
+ s = STR(CHILD(n, 4));
+ /* s[2], the third character in the string, will be
+ 's' for el_s_e, or
+ 'i' for el_i_f
+ */
+ if (s[2] == 's') {
+ expr_ty expression;
+ asdl_seq *seq1, *seq2;
+
+ expression = ast_for_expr(c, CHILD(n, 1));
+ if (!expression)
+ return NULL;
+ seq1 = ast_for_suite(c, CHILD(n, 3));
+ if (!seq1)
+ return NULL;
+ seq2 = ast_for_suite(c, CHILD(n, 6));
+ if (!seq2)
+ return NULL;
+ get_last_end_pos(seq2, &end_lineno, &end_col_offset);
+
+ return If(expression, seq1, seq2, LINENO(n), n->n_col_offset,
+ end_lineno, end_col_offset, c->c_arena);
+ }
+ else if (s[2] == 'i') {
+ int i, n_elif, has_else = 0;
+ expr_ty expression;
+ asdl_seq *suite_seq;
+ asdl_seq *orelse = NULL;
+ n_elif = NCH(n) - 4;
+ /* must reference the child n_elif+1 since 'else' token is third,
+ not fourth, child from the end. */
+ if (TYPE(CHILD(n, (n_elif + 1))) == NAME
+ && STR(CHILD(n, (n_elif + 1)))[2] == 's') {
+ has_else = 1;
+ n_elif -= 3;
+ }
+ n_elif /= 4;
+
+ if (has_else) {
+ asdl_seq *suite_seq2;
+
+ orelse = _Py_asdl_seq_new(1, c->c_arena);
+ if (!orelse)
+ return NULL;
+ expression = ast_for_expr(c, CHILD(n, NCH(n) - 6));
+ if (!expression)
+ return NULL;
+ suite_seq = ast_for_suite(c, CHILD(n, NCH(n) - 4));
+ if (!suite_seq)
+ return NULL;
+ suite_seq2 = ast_for_suite(c, CHILD(n, NCH(n) - 1));
+ if (!suite_seq2)
+ return NULL;
+ get_last_end_pos(suite_seq2, &end_lineno, &end_col_offset);
+
+ asdl_seq_SET(orelse, 0,
+ If(expression, suite_seq, suite_seq2,
+ LINENO(CHILD(n, NCH(n) - 7)),
+ CHILD(n, NCH(n) - 7)->n_col_offset,
+ end_lineno, end_col_offset, c->c_arena));
+ /* the just-created orelse handled the last elif */
+ n_elif--;
+ }
+
+ for (i = 0; i < n_elif; i++) {
+ int off = 5 + (n_elif - i - 1) * 4;
+ asdl_seq *newobj = _Py_asdl_seq_new(1, c->c_arena);
+ if (!newobj)
+ return NULL;
+ expression = ast_for_expr(c, CHILD(n, off));
+ if (!expression)
+ return NULL;
+ suite_seq = ast_for_suite(c, CHILD(n, off + 2));
+ if (!suite_seq)
+ return NULL;
+
+ if (orelse != NULL) {
+ get_last_end_pos(orelse, &end_lineno, &end_col_offset);
+ } else {
+ get_last_end_pos(suite_seq, &end_lineno, &end_col_offset);
+ }
+ asdl_seq_SET(newobj, 0,
+ If(expression, suite_seq, orelse,
+ LINENO(CHILD(n, off - 1)),
+ CHILD(n, off - 1)->n_col_offset,
+ end_lineno, end_col_offset, c->c_arena));
+ orelse = newobj;
+ }
+ expression = ast_for_expr(c, CHILD(n, 1));
+ if (!expression)
+ return NULL;
+ suite_seq = ast_for_suite(c, CHILD(n, 3));
+ if (!suite_seq)
+ return NULL;
+ get_last_end_pos(orelse, &end_lineno, &end_col_offset);
+ return If(expression, suite_seq, orelse,
+ LINENO(n), n->n_col_offset,
+ end_lineno, end_col_offset, c->c_arena);
+ }
+
+ PyErr_Format(PyExc_SystemError,
+ "unexpected token in 'if' statement: %s", s);
+ return NULL;
+}
+
+static stmt_ty
+ast_for_while_stmt(struct compiling *c, const node *n)
+{
+ /* while_stmt: 'while' test ':' suite ['else' ':' suite] */
+ REQ(n, while_stmt);
+ int end_lineno, end_col_offset;
+
+ if (NCH(n) == 4) {
+ expr_ty expression;
+ asdl_seq *suite_seq;
+
+ expression = ast_for_expr(c, CHILD(n, 1));
+ if (!expression)
+ return NULL;
+ suite_seq = ast_for_suite(c, CHILD(n, 3));
+ if (!suite_seq)
+ return NULL;
+ get_last_end_pos(suite_seq, &end_lineno, &end_col_offset);
+ return While(expression, suite_seq, NULL, LINENO(n), n->n_col_offset,
+ end_lineno, end_col_offset, c->c_arena);
+ }
+ else if (NCH(n) == 7) {
+ expr_ty expression;
+ asdl_seq *seq1, *seq2;
+
+ expression = ast_for_expr(c, CHILD(n, 1));
+ if (!expression)
+ return NULL;
+ seq1 = ast_for_suite(c, CHILD(n, 3));
+ if (!seq1)
+ return NULL;
+ seq2 = ast_for_suite(c, CHILD(n, 6));
+ if (!seq2)
+ return NULL;
+ get_last_end_pos(seq2, &end_lineno, &end_col_offset);
+
+ return While(expression, seq1, seq2, LINENO(n), n->n_col_offset,
+ end_lineno, end_col_offset, c->c_arena);
+ }
+
+ PyErr_Format(PyExc_SystemError,
+ "wrong number of tokens for 'while' statement: %d",
+ NCH(n));
+ return NULL;
+}
+
+static stmt_ty
+ast_for_for_stmt(struct compiling *c, const node *n0, bool is_async)
+{
+ const node * const n = is_async ? CHILD(n0, 1) : n0;
+ asdl_seq *_target, *seq = NULL, *suite_seq;
+ expr_ty expression;
+ expr_ty target, first;
+ const node *node_target;
+ int end_lineno, end_col_offset;
+ int has_type_comment;
+ string type_comment;
+
+ if (is_async && c->c_feature_version < 5) {
+ ast_error(c, n,
+ "Async for loops are only supported in Python 3.5 and greater");
+ return NULL;
+ }
+
+ /* for_stmt: 'for' exprlist 'in' testlist ':' [TYPE_COMMENT] suite ['else' ':' suite] */
+ REQ(n, for_stmt);
+
+ has_type_comment = TYPE(CHILD(n, 5)) == TYPE_COMMENT;
+
+ if (NCH(n) == 9 + has_type_comment) {
+ seq = ast_for_suite(c, CHILD(n, 8 + has_type_comment));
+ if (!seq)
+ return NULL;
+ }
+
+ node_target = CHILD(n, 1);
+ _target = ast_for_exprlist(c, node_target, Store);
+ if (!_target)
+ return NULL;
+ /* Check the # of children rather than the length of _target, since
+ for x, in ... has 1 element in _target, but still requires a Tuple. */
+ first = (expr_ty)asdl_seq_GET(_target, 0);
+ if (NCH(node_target) == 1)
+ target = first;
+ else
+ target = Tuple(_target, Store, first->lineno, first->col_offset,
+ node_target->n_end_lineno, node_target->n_end_col_offset,
+ c->c_arena);
+
+ expression = ast_for_testlist(c, CHILD(n, 3));
+ if (!expression)
+ return NULL;
+ suite_seq = ast_for_suite(c, CHILD(n, 5 + has_type_comment));
+ if (!suite_seq)
+ return NULL;
+
+ if (seq != NULL) {
+ get_last_end_pos(seq, &end_lineno, &end_col_offset);
+ } else {
+ get_last_end_pos(suite_seq, &end_lineno, &end_col_offset);
+ }
+
+ if (has_type_comment) {
+ type_comment = NEW_TYPE_COMMENT(CHILD(n, 5));
+ if (!type_comment)
+ return NULL;
+ }
+ else
+ type_comment = NULL;
+
+ if (is_async)
+ return AsyncFor(target, expression, suite_seq, seq, type_comment,
+ LINENO(n0), n0->n_col_offset,
+ end_lineno, end_col_offset, c->c_arena);
+ else
+ return For(target, expression, suite_seq, seq, type_comment,
+ LINENO(n), n->n_col_offset,
+ end_lineno, end_col_offset, c->c_arena);
+}
+
+static excepthandler_ty
+ast_for_except_clause(struct compiling *c, const node *exc, node *body)
+{
+ /* except_clause: 'except' [test ['as' test]] */
+ int end_lineno, end_col_offset;
+ REQ(exc, except_clause);
+ REQ(body, suite);
+
+ if (NCH(exc) == 1) {
+ asdl_seq *suite_seq = ast_for_suite(c, body);
+ if (!suite_seq)
+ return NULL;
+ get_last_end_pos(suite_seq, &end_lineno, &end_col_offset);
+
+ return ExceptHandler(NULL, NULL, suite_seq, LINENO(exc),
+ exc->n_col_offset,
+ end_lineno, end_col_offset, c->c_arena);
+ }
+ else if (NCH(exc) == 2) {
+ expr_ty expression;
+ asdl_seq *suite_seq;
+
+ expression = ast_for_expr(c, CHILD(exc, 1));
+ if (!expression)
+ return NULL;
+ suite_seq = ast_for_suite(c, body);
+ if (!suite_seq)
+ return NULL;
+ get_last_end_pos(suite_seq, &end_lineno, &end_col_offset);
+
+ return ExceptHandler(expression, NULL, suite_seq, LINENO(exc),
+ exc->n_col_offset,
+ end_lineno, end_col_offset, c->c_arena);
+ }
+ else if (NCH(exc) == 4) {
+ asdl_seq *suite_seq;
+ expr_ty expression;
+ identifier e = NEW_IDENTIFIER(CHILD(exc, 3));
+ if (!e)
+ return NULL;
+ if (forbidden_name(c, e, CHILD(exc, 3), 0))
+ return NULL;
+ expression = ast_for_expr(c, CHILD(exc, 1));
+ if (!expression)
+ return NULL;
+ suite_seq = ast_for_suite(c, body);
+ if (!suite_seq)
+ return NULL;
+ get_last_end_pos(suite_seq, &end_lineno, &end_col_offset);
+
+ return ExceptHandler(expression, e, suite_seq, LINENO(exc),
+ exc->n_col_offset,
+ end_lineno, end_col_offset, c->c_arena);
+ }
+
+ PyErr_Format(PyExc_SystemError,
+ "wrong number of children for 'except' clause: %d",
+ NCH(exc));
+ return NULL;
+}
+
+static stmt_ty
+ast_for_try_stmt(struct compiling *c, const node *n)
+{
+ const int nch = NCH(n);
+ int end_lineno, end_col_offset, n_except = (nch - 3)/3;
+ asdl_seq *body, *handlers = NULL, *orelse = NULL, *finally = NULL;
+ excepthandler_ty last_handler;
+
+ REQ(n, try_stmt);
+
+ body = ast_for_suite(c, CHILD(n, 2));
+ if (body == NULL)
+ return NULL;
+
+ if (TYPE(CHILD(n, nch - 3)) == NAME) {
+ if (strcmp(STR(CHILD(n, nch - 3)), "finally") == 0) {
+ if (nch >= 9 && TYPE(CHILD(n, nch - 6)) == NAME) {
+ /* we can assume it's an "else",
+ because nch >= 9 for try-else-finally and
+ it would otherwise have a type of except_clause */
+ orelse = ast_for_suite(c, CHILD(n, nch - 4));
+ if (orelse == NULL)
+ return NULL;
+ n_except--;
+ }
+
+ finally = ast_for_suite(c, CHILD(n, nch - 1));
+ if (finally == NULL)
+ return NULL;
+ n_except--;
+ }
+ else {
+ /* we can assume it's an "else",
+ otherwise it would have a type of except_clause */
+ orelse = ast_for_suite(c, CHILD(n, nch - 1));
+ if (orelse == NULL)
+ return NULL;
+ n_except--;
+ }
+ }
+ else if (TYPE(CHILD(n, nch - 3)) != except_clause) {
+ ast_error(c, n, "malformed 'try' statement");
+ return NULL;
+ }
+
+ if (n_except > 0) {
+ int i;
+ /* process except statements to create a try ... except */
+ handlers = _Py_asdl_seq_new(n_except, c->c_arena);
+ if (handlers == NULL)
+ return NULL;
+
+ for (i = 0; i < n_except; i++) {
+ excepthandler_ty e = ast_for_except_clause(c, CHILD(n, 3 + i * 3),
+ CHILD(n, 5 + i * 3));
+ if (!e)
+ return NULL;
+ asdl_seq_SET(handlers, i, e);
+ }
+ }
+
+ assert(finally != NULL || asdl_seq_LEN(handlers));
+ if (finally != NULL) {
+ // finally is always last
+ get_last_end_pos(finally, &end_lineno, &end_col_offset);
+ } else if (orelse != NULL) {
+ // otherwise else is last
+ get_last_end_pos(orelse, &end_lineno, &end_col_offset);
+ } else {
+ // inline the get_last_end_pos logic due to layout mismatch
+ last_handler = (excepthandler_ty) asdl_seq_GET(handlers, n_except - 1);
+ end_lineno = last_handler->end_lineno;
+ end_col_offset = last_handler->end_col_offset;
+ }
+ return Try(body, handlers, orelse, finally, LINENO(n), n->n_col_offset,
+ end_lineno, end_col_offset, c->c_arena);
+}
+
+/* with_item: test ['as' expr] */
+static withitem_ty
+ast_for_with_item(struct compiling *c, const node *n)
+{
+ expr_ty context_expr, optional_vars = NULL;
+
+ REQ(n, with_item);
+ context_expr = ast_for_expr(c, CHILD(n, 0));
+ if (!context_expr)
+ return NULL;
+ if (NCH(n) == 3) {
+ optional_vars = ast_for_expr(c, CHILD(n, 2));
+
+ if (!optional_vars) {
+ return NULL;
+ }
+ if (!set_context(c, optional_vars, Store, n)) {
+ return NULL;
+ }
+ }
+
+ return withitem(context_expr, optional_vars, c->c_arena);
+}
+
+/* with_stmt: 'with' with_item (',' with_item)* ':' [TYPE_COMMENT] suite */
+static stmt_ty
+ast_for_with_stmt(struct compiling *c, const node *n0, bool is_async)
+{
+ const node * const n = is_async ? CHILD(n0, 1) : n0;
+ int i, n_items, nch_minus_type, has_type_comment, end_lineno, end_col_offset;
+ asdl_seq *items, *body;
+ string type_comment;
+
+ if (is_async && c->c_feature_version < 5) {
+ ast_error(c, n,
+ "Async with statements are only supported in Python 3.5 and greater");
+ return NULL;
+ }
+
+ REQ(n, with_stmt);
+
+ has_type_comment = TYPE(CHILD(n, NCH(n) - 2)) == TYPE_COMMENT;
+ nch_minus_type = NCH(n) - has_type_comment;
+
+ n_items = (nch_minus_type - 2) / 2;
+ items = _Py_asdl_seq_new(n_items, c->c_arena);
+ if (!items)
+ return NULL;
+ for (i = 1; i < nch_minus_type - 2; i += 2) {
+ withitem_ty item = ast_for_with_item(c, CHILD(n, i));
+ if (!item)
+ return NULL;
+ asdl_seq_SET(items, (i - 1) / 2, item);
+ }
+
+ body = ast_for_suite(c, CHILD(n, NCH(n) - 1));
+ if (!body)
+ return NULL;
+ get_last_end_pos(body, &end_lineno, &end_col_offset);
+
+ if (has_type_comment) {
+ type_comment = NEW_TYPE_COMMENT(CHILD(n, NCH(n) - 2));
+ if (!type_comment)
+ return NULL;
+ }
+ else
+ type_comment = NULL;
+
+ if (is_async)
+ return AsyncWith(items, body, type_comment, LINENO(n0), n0->n_col_offset,
+ end_lineno, end_col_offset, c->c_arena);
+ else
+ return With(items, body, type_comment, LINENO(n), n->n_col_offset,
+ end_lineno, end_col_offset, c->c_arena);
+}
+
+static stmt_ty
+ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq)
+{
+ /* classdef: 'class' NAME ['(' arglist ')'] ':' suite */
+ PyObject *classname;
+ asdl_seq *s;
+ expr_ty call;
+ int end_lineno, end_col_offset;
+
+ REQ(n, classdef);
+
+ if (NCH(n) == 4) { /* class NAME ':' suite */
+ s = ast_for_suite(c, CHILD(n, 3));
+ if (!s)
+ return NULL;
+ get_last_end_pos(s, &end_lineno, &end_col_offset);
+
+ classname = NEW_IDENTIFIER(CHILD(n, 1));
+ if (!classname)
+ return NULL;
+ if (forbidden_name(c, classname, CHILD(n, 3), 0))
+ return NULL;
+ return ClassDef(classname, NULL, NULL, s, decorator_seq,
+ LINENO(n), n->n_col_offset,
+ end_lineno, end_col_offset, c->c_arena);
+ }
+
+ if (TYPE(CHILD(n, 3)) == RPAR) { /* class NAME '(' ')' ':' suite */
+ s = ast_for_suite(c, CHILD(n, 5));
+ if (!s)
+ return NULL;
+ get_last_end_pos(s, &end_lineno, &end_col_offset);
+
+ classname = NEW_IDENTIFIER(CHILD(n, 1));
+ if (!classname)
+ return NULL;
+ if (forbidden_name(c, classname, CHILD(n, 3), 0))
+ return NULL;
+ return ClassDef(classname, NULL, NULL, s, decorator_seq,
+ LINENO(n), n->n_col_offset,
+ end_lineno, end_col_offset, c->c_arena);
+ }
+
+ /* class NAME '(' arglist ')' ':' suite */
+ /* build up a fake Call node so we can extract its pieces */
+ {
+ PyObject *dummy_name;
+ expr_ty dummy;
+ dummy_name = NEW_IDENTIFIER(CHILD(n, 1));
+ if (!dummy_name)
+ return NULL;
+ dummy = Name(dummy_name, Load, LINENO(n), n->n_col_offset,
+ CHILD(n, 1)->n_end_lineno, CHILD(n, 1)->n_end_col_offset,
+ c->c_arena);
+ call = ast_for_call(c, CHILD(n, 3), dummy,
+ CHILD(n, 1), NULL, CHILD(n, 4));
+ if (!call)
+ return NULL;
+ }
+ s = ast_for_suite(c, CHILD(n, 6));
+ if (!s)
+ return NULL;
+ get_last_end_pos(s, &end_lineno, &end_col_offset);
+
+ classname = NEW_IDENTIFIER(CHILD(n, 1));
+ if (!classname)
+ return NULL;
+ if (forbidden_name(c, classname, CHILD(n, 1), 0))
+ return NULL;
+
+ return ClassDef(classname, call->v.Call.args, call->v.Call.keywords, s,
+ decorator_seq, LINENO(n), n->n_col_offset,
+ end_lineno, end_col_offset, c->c_arena);
+}
+
+static stmt_ty
+ast_for_stmt(struct compiling *c, const node *n)
+{
+ if (TYPE(n) == stmt) {
+ assert(NCH(n) == 1);
+ n = CHILD(n, 0);
+ }
+ if (TYPE(n) == simple_stmt) {
+ assert(num_stmts(n) == 1);
+ n = CHILD(n, 0);
+ }
+ if (TYPE(n) == small_stmt) {
+ n = CHILD(n, 0);
+ /* small_stmt: expr_stmt | del_stmt | pass_stmt | flow_stmt
+ | import_stmt | global_stmt | nonlocal_stmt | assert_stmt
+ */
+ switch (TYPE(n)) {
+ case expr_stmt:
+ return ast_for_expr_stmt(c, n);
+ case del_stmt:
+ return ast_for_del_stmt(c, n);
+ case pass_stmt:
+ return Pass(LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ case flow_stmt:
+ return ast_for_flow_stmt(c, n);
+ case import_stmt:
+ return ast_for_import_stmt(c, n);
+ case global_stmt:
+ return ast_for_global_stmt(c, n);
+ case nonlocal_stmt:
+ return ast_for_nonlocal_stmt(c, n);
+ case assert_stmt:
+ return ast_for_assert_stmt(c, n);
+ default:
+ PyErr_Format(PyExc_SystemError,
+ "unhandled small_stmt: TYPE=%d NCH=%d\n",
+ TYPE(n), NCH(n));
+ return NULL;
+ }
+ }
+ else {
+ /* compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt
+ | funcdef | classdef | decorated | async_stmt
+ */
+ node *ch = CHILD(n, 0);
+ REQ(n, compound_stmt);
+ switch (TYPE(ch)) {
+ case if_stmt:
+ return ast_for_if_stmt(c, ch);
+ case while_stmt:
+ return ast_for_while_stmt(c, ch);
+ case for_stmt:
+ return ast_for_for_stmt(c, ch, 0);
+ case try_stmt:
+ return ast_for_try_stmt(c, ch);
+ case with_stmt:
+ return ast_for_with_stmt(c, ch, 0);
+ case funcdef:
+ return ast_for_funcdef(c, ch, NULL);
+ case classdef:
+ return ast_for_classdef(c, ch, NULL);
+ case decorated:
+ return ast_for_decorated(c, ch);
+ case async_stmt:
+ return ast_for_async_stmt(c, ch);
+ default:
+ PyErr_Format(PyExc_SystemError,
+ "unhandled compound_stmt: TYPE=%d NCH=%d\n",
+ TYPE(n), NCH(n));
+ return NULL;
+ }
+ }
+}
+
+static PyObject *
+parsenumber_raw(struct compiling *c, const char *s)
+{
+ const char *end;
+ long x;
+ double dx;
+ Py_complex compl;
+ int imflag;
+
+ assert(s != NULL);
+ errno = 0;
+ end = s + strlen(s) - 1;
+ imflag = *end == 'j' || *end == 'J';
+ if (s[0] == '0') {
+ x = (long) PyOS_strtoul(s, (char **)&end, 0);
+ if (x < 0 && errno == 0) {
+ return PyLong_FromString(s, (char **)0, 0);
+ }
+ }
+ else
+ x = PyOS_strtol(s, (char **)&end, 0);
+ if (*end == '\0') {
+ if (errno != 0)
+ return PyLong_FromString(s, (char **)0, 0);
+ return PyLong_FromLong(x);
+ }
+ /* XXX Huge floats may silently fail */
+ if (imflag) {
+ compl.real = 0.;
+ compl.imag = PyOS_string_to_double(s, (char **)&end, NULL);
+ if (compl.imag == -1.0 && PyErr_Occurred())
+ return NULL;
+ return PyComplex_FromCComplex(compl);
+ }
+ else
+ {
+ dx = PyOS_string_to_double(s, NULL, NULL);
+ if (dx == -1.0 && PyErr_Occurred())
+ return NULL;
+ return PyFloat_FromDouble(dx);
+ }
+}
+
+static PyObject *
+parsenumber(struct compiling *c, const char *s)
+{
+ char *dup, *end;
+ PyObject *res = NULL;
+
+ assert(s != NULL);
+
+ if (strchr(s, '_') == NULL) {
+ return parsenumber_raw(c, s);
+ }
+ /* Create a duplicate without underscores. */
+ dup = PyMem_Malloc(strlen(s) + 1);
+ if (dup == NULL) {
+ return PyErr_NoMemory();
+ }
+ end = dup;
+ for (; *s; s++) {
+ if (*s != '_') {
+ *end++ = *s;
+ }
+ }
+ *end = '\0';
+ res = parsenumber_raw(c, dup);
+ PyMem_Free(dup);
+ return res;
+}
+
+static PyObject *
+decode_utf8(struct compiling *c, const char **sPtr, const char *end)
+{
+ const char *s, *t;
+ t = s = *sPtr;
+ /* while (s < end && *s != '\\') s++; */ /* inefficient for u".." */
+ while (s < end && (*s & 0x80)) s++;
+ *sPtr = s;
+ return PyUnicode_DecodeUTF8(t, s - t, NULL);
+}
+
+static int
+warn_invalid_escape_sequence(struct compiling *c, const node *n,
+ unsigned char first_invalid_escape_char)
+{
+ PyObject *msg = PyUnicode_FromFormat("invalid escape sequence \\%c",
+ first_invalid_escape_char);
+ if (msg == NULL) {
+ return -1;
+ }
+ if (PyErr_WarnExplicitObject(PyExc_DeprecationWarning, msg,
+ c->c_filename, LINENO(n),
+ NULL, NULL) < 0)
+ {
+ if (PyErr_ExceptionMatches(PyExc_DeprecationWarning)) {
+ /* Replace the DeprecationWarning exception with a SyntaxError
+ to get a more accurate error report */
+ PyErr_Clear();
+ ast_error(c, n, "%U", msg);
+ }
+ Py_DECREF(msg);
+ return -1;
+ }
+ Py_DECREF(msg);
+ return 0;
+}
+
+static PyObject *
+decode_unicode_with_escapes(struct compiling *c, const node *n, const char *s,
+ size_t len)
+{
+ PyObject *v, *u;
+ char *buf;
+ char *p;
+ const char *end;
+
+ /* check for integer overflow */
+ if (len > SIZE_MAX / 6)
+ return NULL;
+ /* "ä" (2 bytes) may become "\U000000E4" (10 bytes), or 1:5
+ "\ä" (3 bytes) may become "\u005c\U000000E4" (16 bytes), or ~1:6 */
+ u = PyBytes_FromStringAndSize((char *)NULL, len * 6);
+ if (u == NULL)
+ return NULL;
+ p = buf = PyBytes_AsString(u);
+ end = s + len;
+ while (s < end) {
+ if (*s == '\\') {
+ *p++ = *s++;
+ if (s >= end || *s & 0x80) {
+ strcpy(p, "u005c");
+ p += 5;
+ if (s >= end)
+ break;
+ }
+ }
+ if (*s & 0x80) { /* XXX inefficient */
+ PyObject *w;
+ int kind;
+ const void *data;
+ Py_ssize_t len, i;
+ w = decode_utf8(c, &s, end);
+ if (w == NULL) {
+ Py_DECREF(u);
+ return NULL;
+ }
+ kind = PyUnicode_KIND(w);
+ data = PyUnicode_DATA(w);
+ len = PyUnicode_GET_LENGTH(w);
+ for (i = 0; i < len; i++) {
+ Py_UCS4 chr = PyUnicode_READ(kind, data, i);
+ sprintf(p, "\\U%08x", chr);
+ p += 10;
+ }
+ /* Should be impossible to overflow */
+ assert(p - buf <= PyBytes_GET_SIZE(u));
+ Py_DECREF(w);
+ } else {
+ *p++ = *s++;
+ }
+ }
+ len = p - buf;
+ s = buf;
+
+ const char *first_invalid_escape;
+ v = _PyUnicode_DecodeUnicodeEscapeInternal(s, len, NULL, NULL, &first_invalid_escape);
+
+ if (v != NULL && first_invalid_escape != NULL) {
+ if (warn_invalid_escape_sequence(c, n, *first_invalid_escape) < 0) {
+ /* We have not decref u before because first_invalid_escape points
+ inside u. */
+ Py_XDECREF(u);
+ Py_DECREF(v);
+ return NULL;
+ }
+ }
+ Py_XDECREF(u);
+ return v;
+}
+
+static PyObject *
+decode_bytes_with_escapes(struct compiling *c, const node *n, const char *s,
+ size_t len)
+{
+ const char *first_invalid_escape;
+ PyObject *result = _PyBytes_DecodeEscape(s, len, NULL,
+ &first_invalid_escape);
+ if (result == NULL)
+ return NULL;
+
+ if (first_invalid_escape != NULL) {
+ if (warn_invalid_escape_sequence(c, n, *first_invalid_escape) < 0) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ }
+ return result;
+}
+
+/* Shift locations for the given node and all its children by adding `lineno`
+ and `col_offset` to existing locations. */
+static void fstring_shift_node_locations(node *n, int lineno, int col_offset)
+{
+ n->n_col_offset = n->n_col_offset + col_offset;
+ n->n_end_col_offset = n->n_end_col_offset + col_offset;
+ for (int i = 0; i < NCH(n); ++i) {
+ if (n->n_lineno && n->n_lineno < CHILD(n, i)->n_lineno) {
+ /* Shifting column offsets unnecessary if there's been newlines. */
+ col_offset = 0;
+ }
+ fstring_shift_node_locations(CHILD(n, i), lineno, col_offset);
+ }
+ n->n_lineno = n->n_lineno + lineno;
+ n->n_end_lineno = n->n_end_lineno + lineno;
+}
+
+/* Fix locations for the given node and its children.
+
+ `parent` is the enclosing node.
+ `n` is the node which locations are going to be fixed relative to parent.
+ `expr_str` is the child node's string representation, including braces.
+*/
+static void
+fstring_fix_node_location(const node *parent, node *n, char *expr_str)
+{
+ char *substr = NULL;
+ char *start;
+ int lines = LINENO(parent) - 1;
+ int cols = parent->n_col_offset;
+ /* Find the full fstring to fix location information in `n`. */
+ while (parent && parent->n_type != STRING)
+ parent = parent->n_child;
+ if (parent && parent->n_str) {
+ substr = strstr(parent->n_str, expr_str);
+ if (substr) {
+ start = substr;
+ while (start > parent->n_str) {
+ if (start[0] == '\n')
+ break;
+ start--;
+ }
+ cols += (int)(substr - start);
+ /* adjust the start based on the number of newlines encountered
+ before the f-string expression */
+ for (char* p = parent->n_str; p < substr; p++) {
+ if (*p == '\n') {
+ lines++;
+ }
+ }
+ }
+ }
+ fstring_shift_node_locations(n, lines, cols);
+}
+
+/* Compile this expression in to an expr_ty. Add parens around the
+ expression, in order to allow leading spaces in the expression. */
+static expr_ty
+fstring_compile_expr(const char *expr_start, const char *expr_end,
+ struct compiling *c, const node *n)
+
+{
+ node *mod_n;
+ mod_ty mod;
+ char *str;
+ Py_ssize_t len;
+ const char *s;
+
+ assert(expr_end >= expr_start);
+ assert(*(expr_start-1) == '{');
+ assert(*expr_end == '}' || *expr_end == '!' || *expr_end == ':' ||
+ *expr_end == '=');
+
+ /* If the substring is all whitespace, it's an error. We need to catch this
+ here, and not when we call PyParser_SimpleParseStringFlagsFilename,
+ because turning the expression '' in to '()' would go from being invalid
+ to valid. */
+ for (s = expr_start; s != expr_end; s++) {
+ char c = *s;
+ /* The Python parser ignores only the following whitespace
+ characters (\r already is converted to \n). */
+ if (!(c == ' ' || c == '\t' || c == '\n' || c == '\f')) {
+ break;
+ }
+ }
+ if (s == expr_end) {
+ ast_error(c, n, "f-string: empty expression not allowed");
+ return NULL;
+ }
+
+ len = expr_end - expr_start;
+ /* Allocate 3 extra bytes: open paren, close paren, null byte. */
+ str = PyMem_Malloc(len + 3);
+ if (str == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ str[0] = '(';
+ memcpy(str+1, expr_start, len);
+ str[len+1] = ')';
+ str[len+2] = 0;
+
+ PyCompilerFlags cf = _PyCompilerFlags_INIT;
+ cf.cf_flags = PyCF_ONLY_AST;
+ mod_n = PyParser_SimpleParseStringFlagsFilename(str, "<fstring>",
+ Py_eval_input, 0);
+ if (!mod_n) {
+ PyMem_Free(str);
+ return NULL;
+ }
+ /* Reuse str to find the correct column offset. */
+ str[0] = '{';
+ str[len+1] = '}';
+ fstring_fix_node_location(n, mod_n, str);
+ mod = PyAST_FromNode(mod_n, &cf, "<fstring>", c->c_arena);
+ PyMem_Free(str);
+ PyNode_Free(mod_n);
+ if (!mod)
+ return NULL;
+ return mod->v.Expression.body;
+}
+
+/* Return -1 on error.
+
+ Return 0 if we reached the end of the literal.
+
+ Return 1 if we haven't reached the end of the literal, but we want
+ the caller to process the literal up to this point. Used for
+ doubled braces.
+*/
+static int
+fstring_find_literal(const char **str, const char *end, int raw,
+ PyObject **literal, int recurse_lvl,
+ struct compiling *c, const node *n)
+{
+ /* Get any literal string. It ends when we hit an un-doubled left
+ brace (which isn't part of a unicode name escape such as
+ "\N{EULER CONSTANT}"), or the end of the string. */
+
+ const char *s = *str;
+ const char *literal_start = s;
+ int result = 0;
+
+ assert(*literal == NULL);
+ while (s < end) {
+ char ch = *s++;
+ if (!raw && ch == '\\' && s < end) {
+ ch = *s++;
+ if (ch == 'N') {
+ if (s < end && *s++ == '{') {
+ while (s < end && *s++ != '}') {
+ }
+ continue;
+ }
+ break;
+ }
+ if (ch == '{' && warn_invalid_escape_sequence(c, n, ch) < 0) {
+ return -1;
+ }
+ }
+ if (ch == '{' || ch == '}') {
+ /* Check for doubled braces, but only at the top level. If
+ we checked at every level, then f'{0:{3}}' would fail
+ with the two closing braces. */
+ if (recurse_lvl == 0) {
+ if (s < end && *s == ch) {
+ /* We're going to tell the caller that the literal ends
+ here, but that they should continue scanning. But also
+ skip over the second brace when we resume scanning. */
+ *str = s + 1;
+ result = 1;
+ goto done;
+ }
+
+ /* Where a single '{' is the start of a new expression, a
+ single '}' is not allowed. */
+ if (ch == '}') {
+ *str = s - 1;
+ ast_error(c, n, "f-string: single '}' is not allowed");
+ return -1;
+ }
+ }
+ /* We're either at a '{', which means we're starting another
+ expression; or a '}', which means we're at the end of this
+ f-string (for a nested format_spec). */
+ s--;
+ break;
+ }
+ }
+ *str = s;
+ assert(s <= end);
+ assert(s == end || *s == '{' || *s == '}');
+done:
+ if (literal_start != s) {
+ if (raw)
+ *literal = PyUnicode_DecodeUTF8Stateful(literal_start,
+ s - literal_start,
+ NULL, NULL);
+ else
+ *literal = decode_unicode_with_escapes(c, n, literal_start,
+ s - literal_start);
+ if (!*literal)
+ return -1;
+ }
+ return result;
+}
+
+/* Forward declaration because parsing is recursive. */
+static expr_ty
+fstring_parse(const char **str, const char *end, int raw, int recurse_lvl,
+ struct compiling *c, const node *n);
+
+/* Parse the f-string at *str, ending at end. We know *str starts an
+ expression (so it must be a '{'). Returns the FormattedValue node, which
+ includes the expression, conversion character, format_spec expression, and
+ optionally the text of the expression (if = is used).
+
+ Note that I don't do a perfect job here: I don't make sure that a
+ closing brace doesn't match an opening paren, for example. It
+ doesn't need to error on all invalid expressions, just correctly
+ find the end of all valid ones. Any errors inside the expression
+ will be caught when we parse it later.
+
+ *expression is set to the expression. For an '=' "debug" expression,
+ *expr_text is set to the debug text (the original text of the expression,
+ including the '=' and any whitespace around it, as a string object). If
+ not a debug expression, *expr_text set to NULL. */
+static int
+fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl,
+ PyObject **expr_text, expr_ty *expression,
+ struct compiling *c, const node *n)
+{
+ /* Return -1 on error, else 0. */
+
+ const char *expr_start;
+ const char *expr_end;
+ expr_ty simple_expression;
+ expr_ty format_spec = NULL; /* Optional format specifier. */
+ int conversion = -1; /* The conversion char. Use default if not
+ specified, or !r if using = and no format
+ spec. */
+
+ /* 0 if we're not in a string, else the quote char we're trying to
+ match (single or double quote). */
+ char quote_char = 0;
+
+ /* If we're inside a string, 1=normal, 3=triple-quoted. */
+ int string_type = 0;
+
+ /* Keep track of nesting level for braces/parens/brackets in
+ expressions. */
+ Py_ssize_t nested_depth = 0;
+ char parenstack[MAXLEVEL];
+
+ *expr_text = NULL;
+
+ /* Can only nest one level deep. */
+ if (recurse_lvl >= 2) {
+ ast_error(c, n, "f-string: expressions nested too deeply");
+ goto error;
+ }
+
+ /* The first char must be a left brace, or we wouldn't have gotten
+ here. Skip over it. */
+ assert(**str == '{');
+ *str += 1;
+
+ expr_start = *str;
+ for (; *str < end; (*str)++) {
+ char ch;
+
+ /* Loop invariants. */
+ assert(nested_depth >= 0);
+ assert(*str >= expr_start && *str < end);
+ if (quote_char)
+ assert(string_type == 1 || string_type == 3);
+ else
+ assert(string_type == 0);
+
+ ch = **str;
+ /* Nowhere inside an expression is a backslash allowed. */
+ if (ch == '\\') {
+ /* Error: can't include a backslash character, inside
+ parens or strings or not. */
+ ast_error(c, n,
+ "f-string expression part "
+ "cannot include a backslash");
+ goto error;
+ }
+ if (quote_char) {
+ /* We're inside a string. See if we're at the end. */
+ /* This code needs to implement the same non-error logic
+ as tok_get from tokenizer.c, at the letter_quote
+ label. To actually share that code would be a
+ nightmare. But, it's unlikely to change and is small,
+ so duplicate it here. Note we don't need to catch all
+ of the errors, since they'll be caught when parsing the
+ expression. We just need to match the non-error
+ cases. Thus we can ignore \n in single-quoted strings,
+ for example. Or non-terminated strings. */
+ if (ch == quote_char) {
+ /* Does this match the string_type (single or triple
+ quoted)? */
+ if (string_type == 3) {
+ if (*str+2 < end && *(*str+1) == ch && *(*str+2) == ch) {
+ /* We're at the end of a triple quoted string. */
+ *str += 2;
+ string_type = 0;
+ quote_char = 0;
+ continue;
+ }
+ } else {
+ /* We're at the end of a normal string. */
+ quote_char = 0;
+ string_type = 0;
+ continue;
+ }
+ }
+ } else if (ch == '\'' || ch == '"') {
+ /* Is this a triple quoted string? */
+ if (*str+2 < end && *(*str+1) == ch && *(*str+2) == ch) {
+ string_type = 3;
+ *str += 2;
+ } else {
+ /* Start of a normal string. */
+ string_type = 1;
+ }
+ /* Start looking for the end of the string. */
+ quote_char = ch;
+ } else if (ch == '[' || ch == '{' || ch == '(') {
+ if (nested_depth >= MAXLEVEL) {
+ ast_error(c, n, "f-string: too many nested parenthesis");
+ goto error;
+ }
+ parenstack[nested_depth] = ch;
+ nested_depth++;
+ } else if (ch == '#') {
+ /* Error: can't include a comment character, inside parens
+ or not. */
+ ast_error(c, n, "f-string expression part cannot include '#'");
+ goto error;
+ } else if (nested_depth == 0 &&
+ (ch == '!' || ch == ':' || ch == '}' ||
+ ch == '=' || ch == '>' || ch == '<')) {
+ /* See if there's a next character. */
+ if (*str+1 < end) {
+ char next = *(*str+1);
+
+ /* For "!=". since '=' is not an allowed conversion character,
+ nothing is lost in this test. */
+ if ((ch == '!' && next == '=') || /* != */
+ (ch == '=' && next == '=') || /* == */
+ (ch == '<' && next == '=') || /* <= */
+ (ch == '>' && next == '=') /* >= */
+ ) {
+ *str += 1;
+ continue;
+ }
+ /* Don't get out of the loop for these, if they're single
+ chars (not part of 2-char tokens). If by themselves, they
+ don't end an expression (unlike say '!'). */
+ if (ch == '>' || ch == '<') {
+ continue;
+ }
+ }
+
+ /* Normal way out of this loop. */
+ break;
+ } else if (ch == ']' || ch == '}' || ch == ')') {
+ if (!nested_depth) {
+ ast_error(c, n, "f-string: unmatched '%c'", ch);
+ goto error;
+ }
+ nested_depth--;
+ int opening = parenstack[nested_depth];
+ if (!((opening == '(' && ch == ')') ||
+ (opening == '[' && ch == ']') ||
+ (opening == '{' && ch == '}')))
+ {
+ ast_error(c, n,
+ "f-string: closing parenthesis '%c' "
+ "does not match opening parenthesis '%c'",
+ ch, opening);
+ goto error;
+ }
+ } else {
+ /* Just consume this char and loop around. */
+ }
+ }
+ expr_end = *str;
+ /* If we leave this loop in a string or with mismatched parens, we
+ don't care. We'll get a syntax error when compiling the
+ expression. But, we can produce a better error message, so
+ let's just do that.*/
+ if (quote_char) {
+ ast_error(c, n, "f-string: unterminated string");
+ goto error;
+ }
+ if (nested_depth) {
+ int opening = parenstack[nested_depth - 1];
+ ast_error(c, n, "f-string: unmatched '%c'", opening);
+ goto error;
+ }
+
+ if (*str >= end)
+ goto unexpected_end_of_string;
+
+ /* Compile the expression as soon as possible, so we show errors
+ related to the expression before errors related to the
+ conversion or format_spec. */
+ simple_expression = fstring_compile_expr(expr_start, expr_end, c, n);
+ if (!simple_expression)
+ goto error;
+
+ /* Check for =, which puts the text value of the expression in
+ expr_text. */
+ if (**str == '=') {
+ if (c->c_feature_version < 8) {
+ ast_error(c, n,
+ "f-string: self documenting expressions are "
+ "only supported in Python 3.8 and greater");
+ goto error;
+ }
+ *str += 1;
+
+ /* Skip over ASCII whitespace. No need to test for end of string
+ here, since we know there's at least a trailing quote somewhere
+ ahead. */
+ while (Py_ISSPACE(**str)) {
+ *str += 1;
+ }
+
+ /* Set *expr_text to the text of the expression. */
+ *expr_text = PyUnicode_FromStringAndSize(expr_start, *str-expr_start);
+ if (!*expr_text) {
+ goto error;
+ }
+ }
+
+ /* Check for a conversion char, if present. */
+ if (**str == '!') {
+ *str += 1;
+ if (*str >= end)
+ goto unexpected_end_of_string;
+
+ conversion = **str;
+ *str += 1;
+
+ /* Validate the conversion. */
+ if (!(conversion == 's' || conversion == 'r' || conversion == 'a')) {
+ ast_error(c, n,
+ "f-string: invalid conversion character: "
+ "expected 's', 'r', or 'a'");
+ goto error;
+ }
+
+ }
+
+ /* Check for the format spec, if present. */
+ if (*str >= end)
+ goto unexpected_end_of_string;
+ if (**str == ':') {
+ *str += 1;
+ if (*str >= end)
+ goto unexpected_end_of_string;
+
+ /* Parse the format spec. */
+ format_spec = fstring_parse(str, end, raw, recurse_lvl+1, c, n);
+ if (!format_spec)
+ goto error;
+ }
+
+ if (*str >= end || **str != '}')
+ goto unexpected_end_of_string;
+
+ /* We're at a right brace. Consume it. */
+ assert(*str < end);
+ assert(**str == '}');
+ *str += 1;
+
+ /* If we're in = mode (detected by non-NULL expr_text), and have no format
+ spec and no explicit conversion, set the conversion to 'r'. */
+ if (*expr_text && format_spec == NULL && conversion == -1) {
+ conversion = 'r';
+ }
+
+ /* And now create the FormattedValue node that represents this
+ entire expression with the conversion and format spec. */
+ *expression = FormattedValue(simple_expression, conversion,
+ format_spec, LINENO(n),
+ n->n_col_offset, n->n_end_lineno,
+ n->n_end_col_offset, c->c_arena);
+ if (!*expression)
+ goto error;
+
+ return 0;
+
+unexpected_end_of_string:
+ ast_error(c, n, "f-string: expecting '}'");
+ /* Falls through to error. */
+
+error:
+ Py_XDECREF(*expr_text);
+ return -1;
+
+}
+
+/* Return -1 on error.
+
+ Return 0 if we have a literal (possible zero length) and an
+ expression (zero length if at the end of the string.
+
+ Return 1 if we have a literal, but no expression, and we want the
+ caller to call us again. This is used to deal with doubled
+ braces.
+
+ When called multiple times on the string 'a{{b{0}c', this function
+ will return:
+
+ 1. the literal 'a{' with no expression, and a return value
+ of 1. Despite the fact that there's no expression, the return
+ value of 1 means we're not finished yet.
+
+ 2. the literal 'b' and the expression '0', with a return value of
+ 0. The fact that there's an expression means we're not finished.
+
+ 3. literal 'c' with no expression and a return value of 0. The
+ combination of the return value of 0 with no expression means
+ we're finished.
+*/
+static int
+fstring_find_literal_and_expr(const char **str, const char *end, int raw,
+ int recurse_lvl, PyObject **literal,
+ PyObject **expr_text, expr_ty *expression,
+ struct compiling *c, const node *n)
+{
+ int result;
+
+ assert(*literal == NULL && *expression == NULL);
+
+ /* Get any literal string. */
+ result = fstring_find_literal(str, end, raw, literal, recurse_lvl, c, n);
+ if (result < 0)
+ goto error;
+
+ assert(result == 0 || result == 1);
+
+ if (result == 1)
+ /* We have a literal, but don't look at the expression. */
+ return 1;
+
+ if (*str >= end || **str == '}')
+ /* We're at the end of the string or the end of a nested
+ f-string: no expression. The top-level error case where we
+ expect to be at the end of the string but we're at a '}' is
+ handled later. */
+ return 0;
+
+ /* We must now be the start of an expression, on a '{'. */
+ assert(**str == '{');
+
+ if (fstring_find_expr(str, end, raw, recurse_lvl, expr_text,
+ expression, c, n) < 0)
+ goto error;
+
+ return 0;
+
+error:
+ Py_CLEAR(*literal);
+ return -1;
+}
+
+#define EXPRLIST_N_CACHED 64
+
+typedef struct {
+ /* Incrementally build an array of expr_ty, so be used in an
+ asdl_seq. Cache some small but reasonably sized number of
+ expr_ty's, and then after that start dynamically allocating,
+ doubling the number allocated each time. Note that the f-string
+ f'{0}a{1}' contains 3 expr_ty's: 2 FormattedValue's, and one
+ Constant for the literal 'a'. So you add expr_ty's about twice as
+ fast as you add expressions in an f-string. */
+
+ Py_ssize_t allocated; /* Number we've allocated. */
+ Py_ssize_t size; /* Number we've used. */
+ expr_ty *p; /* Pointer to the memory we're actually
+ using. Will point to 'data' until we
+ start dynamically allocating. */
+ expr_ty data[EXPRLIST_N_CACHED];
+} ExprList;
+
+#ifdef NDEBUG
+#define ExprList_check_invariants(l)
+#else
+static void
+ExprList_check_invariants(ExprList *l)
+{
+ /* Check our invariants. Make sure this object is "live", and
+ hasn't been deallocated. */
+ assert(l->size >= 0);
+ assert(l->p != NULL);
+ if (l->size <= EXPRLIST_N_CACHED)
+ assert(l->data == l->p);
+}
+#endif
+
+static void
+ExprList_Init(ExprList *l)
+{
+ l->allocated = EXPRLIST_N_CACHED;
+ l->size = 0;
+
+ /* Until we start allocating dynamically, p points to data. */
+ l->p = l->data;
+
+ ExprList_check_invariants(l);
+}
+
+static int
+ExprList_Append(ExprList *l, expr_ty exp)
+{
+ ExprList_check_invariants(l);
+ if (l->size >= l->allocated) {
+ /* We need to alloc (or realloc) the memory. */
+ Py_ssize_t new_size = l->allocated * 2;
+
+ /* See if we've ever allocated anything dynamically. */
+ if (l->p == l->data) {
+ Py_ssize_t i;
+ /* We're still using the cached data. Switch to
+ alloc-ing. */
+ l->p = PyMem_Malloc(sizeof(expr_ty) * new_size);
+ if (!l->p)
+ return -1;
+ /* Copy the cached data into the new buffer. */
+ for (i = 0; i < l->size; i++)
+ l->p[i] = l->data[i];
+ } else {
+ /* Just realloc. */
+ expr_ty *tmp = PyMem_Realloc(l->p, sizeof(expr_ty) * new_size);
+ if (!tmp) {
+ PyMem_Free(l->p);
+ l->p = NULL;
+ return -1;
+ }
+ l->p = tmp;
+ }
+
+ l->allocated = new_size;
+ assert(l->allocated == 2 * l->size);
+ }
+
+ l->p[l->size++] = exp;
+
+ ExprList_check_invariants(l);
+ return 0;
+}
+
+static void
+ExprList_Dealloc(ExprList *l)
+{
+ ExprList_check_invariants(l);
+
+ /* If there's been an error, or we've never dynamically allocated,
+ do nothing. */
+ if (!l->p || l->p == l->data) {
+ /* Do nothing. */
+ } else {
+ /* We have dynamically allocated. Free the memory. */
+ PyMem_Free(l->p);
+ }
+ l->p = NULL;
+ l->size = -1;
+}
+
+static asdl_seq *
+ExprList_Finish(ExprList *l, PyArena *arena)
+{
+ asdl_seq *seq;
+
+ ExprList_check_invariants(l);
+
+ /* Allocate the asdl_seq and copy the expressions in to it. */
+ seq = _Py_asdl_seq_new(l->size, arena);
+ if (seq) {
+ Py_ssize_t i;
+ for (i = 0; i < l->size; i++)
+ asdl_seq_SET(seq, i, l->p[i]);
+ }
+ ExprList_Dealloc(l);
+ return seq;
+}
+
+/* The FstringParser is designed to add a mix of strings and
+ f-strings, and concat them together as needed. Ultimately, it
+ generates an expr_ty. */
+typedef struct {
+ PyObject *last_str;
+ ExprList expr_list;
+ int fmode;
+} FstringParser;
+
+#ifdef NDEBUG
+#define FstringParser_check_invariants(state)
+#else
+static void
+FstringParser_check_invariants(FstringParser *state)
+{
+ if (state->last_str)
+ assert(PyUnicode_CheckExact(state->last_str));
+ ExprList_check_invariants(&state->expr_list);
+}
+#endif
+
+static void
+FstringParser_Init(FstringParser *state)
+{
+ state->last_str = NULL;
+ state->fmode = 0;
+ ExprList_Init(&state->expr_list);
+ FstringParser_check_invariants(state);
+}
+
+static void
+FstringParser_Dealloc(FstringParser *state)
+{
+ FstringParser_check_invariants(state);
+
+ Py_XDECREF(state->last_str);
+ ExprList_Dealloc(&state->expr_list);
+}
+
+/* Constants for the following */
+static PyObject *u_kind;
+
+/* Compute 'kind' field for string Constant (either 'u' or None) */
+static PyObject *
+make_kind(struct compiling *c, const node *n)
+{
+ char *s = NULL;
+ PyObject *kind = NULL;
+
+ /* Find the first string literal, if any */
+ while (TYPE(n) != STRING) {
+ if (NCH(n) == 0)
+ return NULL;
+ n = CHILD(n, 0);
+ }
+ REQ(n, STRING);
+
+ /* If it starts with 'u', return a PyUnicode "u" string */
+ s = STR(n);
+ if (s && *s == 'u') {
+ if (!u_kind) {
+ u_kind = PyUnicode_InternFromString("u");
+ if (!u_kind)
+ return NULL;
+ }
+ kind = u_kind;
+ if (PyArena_AddPyObject(c->c_arena, kind) < 0) {
+ return NULL;
+ }
+ Py_INCREF(kind);
+ }
+ return kind;
+}
+
+/* Make a Constant node, but decref the PyUnicode object being added. */
+static expr_ty
+make_str_node_and_del(PyObject **str, struct compiling *c, const node* n)
+{
+ PyObject *s = *str;
+ PyObject *kind = NULL;
+ *str = NULL;
+ assert(PyUnicode_CheckExact(s));
+ if (PyArena_AddPyObject(c->c_arena, s) < 0) {
+ Py_DECREF(s);
+ return NULL;
+ }
+ kind = make_kind(c, n);
+ if (kind == NULL && PyErr_Occurred())
+ return NULL;
+ return Constant(s, kind, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+}
+
+/* Add a non-f-string (that is, a regular literal string). str is
+ decref'd. */
+static int
+FstringParser_ConcatAndDel(FstringParser *state, PyObject *str)
+{
+ FstringParser_check_invariants(state);
+
+ assert(PyUnicode_CheckExact(str));
+
+ if (PyUnicode_GET_LENGTH(str) == 0) {
+ Py_DECREF(str);
+ return 0;
+ }
+
+ if (!state->last_str) {
+ /* We didn't have a string before, so just remember this one. */
+ state->last_str = str;
+ } else {
+ /* Concatenate this with the previous string. */
+ PyUnicode_AppendAndDel(&state->last_str, str);
+ if (!state->last_str)
+ return -1;
+ }
+ FstringParser_check_invariants(state);
+ return 0;
+}
+
+/* Parse an f-string. The f-string is in *str to end, with no
+ 'f' or quotes. */
+static int
+FstringParser_ConcatFstring(FstringParser *state, const char **str,
+ const char *end, int raw, int recurse_lvl,
+ struct compiling *c, const node *n)
+{
+ FstringParser_check_invariants(state);
+ state->fmode = 1;
+
+ /* Parse the f-string. */
+ while (1) {
+ PyObject *literal = NULL;
+ PyObject *expr_text = NULL;
+ expr_ty expression = NULL;
+
+ /* If there's a zero length literal in front of the
+ expression, literal will be NULL. If we're at the end of
+ the f-string, expression will be NULL (unless result == 1,
+ see below). */
+ int result = fstring_find_literal_and_expr(str, end, raw, recurse_lvl,
+ &literal, &expr_text,
+ &expression, c, n);
+ if (result < 0)
+ return -1;
+
+ /* Add the literal, if any. */
+ if (literal && FstringParser_ConcatAndDel(state, literal) < 0) {
+ Py_XDECREF(expr_text);
+ return -1;
+ }
+ /* Add the expr_text, if any. */
+ if (expr_text && FstringParser_ConcatAndDel(state, expr_text) < 0) {
+ return -1;
+ }
+
+ /* We've dealt with the literal and expr_text, their ownership has
+ been transferred to the state object. Don't look at them again. */
+
+ /* See if we should just loop around to get the next literal
+ and expression, while ignoring the expression this
+ time. This is used for un-doubling braces, as an
+ optimization. */
+ if (result == 1)
+ continue;
+
+ if (!expression)
+ /* We're done with this f-string. */
+ break;
+
+ /* We know we have an expression. Convert any existing string
+ to a Constant node. */
+ if (!state->last_str) {
+ /* Do nothing. No previous literal. */
+ } else {
+ /* Convert the existing last_str literal to a Constant node. */
+ expr_ty str = make_str_node_and_del(&state->last_str, c, n);
+ if (!str || ExprList_Append(&state->expr_list, str) < 0)
+ return -1;
+ }
+
+ if (ExprList_Append(&state->expr_list, expression) < 0)
+ return -1;
+ }
+
+ /* If recurse_lvl is zero, then we must be at the end of the
+ string. Otherwise, we must be at a right brace. */
+
+ if (recurse_lvl == 0 && *str < end-1) {
+ ast_error(c, n, "f-string: unexpected end of string");
+ return -1;
+ }
+ if (recurse_lvl != 0 && **str != '}') {
+ ast_error(c, n, "f-string: expecting '}'");
+ return -1;
+ }
+
+ FstringParser_check_invariants(state);
+ return 0;
+}
+
+/* Convert the partial state reflected in last_str and expr_list to an
+ expr_ty. The expr_ty can be a Constant, or a JoinedStr. */
+static expr_ty
+FstringParser_Finish(FstringParser *state, struct compiling *c,
+ const node *n)
+{
+ asdl_seq *seq;
+
+ FstringParser_check_invariants(state);
+
+ /* If we're just a constant string with no expressions, return
+ that. */
+ if (!state->fmode) {
+ assert(!state->expr_list.size);
+ if (!state->last_str) {
+ /* Create a zero length string. */
+ state->last_str = PyUnicode_FromStringAndSize(NULL, 0);
+ if (!state->last_str)
+ goto error;
+ }
+ return make_str_node_and_del(&state->last_str, c, n);
+ }
+
+ /* Create a Constant node out of last_str, if needed. It will be the
+ last node in our expression list. */
+ if (state->last_str) {
+ expr_ty str = make_str_node_and_del(&state->last_str, c, n);
+ if (!str || ExprList_Append(&state->expr_list, str) < 0)
+ goto error;
+ }
+ /* This has already been freed. */
+ assert(state->last_str == NULL);
+
+ seq = ExprList_Finish(&state->expr_list, c->c_arena);
+ if (!seq)
+ goto error;
+
+ return JoinedStr(seq, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+
+error:
+ FstringParser_Dealloc(state);
+ return NULL;
+}
+
+/* Given an f-string (with no 'f' or quotes) that's in *str and ends
+ at end, parse it into an expr_ty. Return NULL on error. Adjust
+ str to point past the parsed portion. */
+static expr_ty
+fstring_parse(const char **str, const char *end, int raw, int recurse_lvl,
+ struct compiling *c, const node *n)
+{
+ FstringParser state;
+
+ FstringParser_Init(&state);
+ if (FstringParser_ConcatFstring(&state, str, end, raw, recurse_lvl,
+ c, n) < 0) {
+ FstringParser_Dealloc(&state);
+ return NULL;
+ }
+
+ return FstringParser_Finish(&state, c, n);
+}
+
+/* n is a Python string literal, including the bracketing quote
+ characters, and r, b, u, &/or f prefixes (if any), and embedded
+ escape sequences (if any). parsestr parses it, and sets *result to
+ decoded Python string object. If the string is an f-string, set
+ *fstr and *fstrlen to the unparsed string object. Return 0 if no
+ errors occurred.
+*/
+static int
+parsestr(struct compiling *c, const node *n, int *bytesmode, int *rawmode,
+ PyObject **result, const char **fstr, Py_ssize_t *fstrlen)
+{
+ size_t len;
+ const char *s = STR(n);
+ int quote = Py_CHARMASK(*s);
+ int fmode = 0;
+ *bytesmode = 0;
+ *rawmode = 0;
+ *result = NULL;
+ *fstr = NULL;
+ if (Py_ISALPHA(quote)) {
+ while (!*bytesmode || !*rawmode) {
+ if (quote == 'b' || quote == 'B') {
+ quote = *++s;
+ *bytesmode = 1;
+ }
+ else if (quote == 'u' || quote == 'U') {
+ quote = *++s;
+ }
+ else if (quote == 'r' || quote == 'R') {
+ quote = *++s;
+ *rawmode = 1;
+ }
+ else if (quote == 'f' || quote == 'F') {
+ quote = *++s;
+ fmode = 1;
+ }
+ else {
+ break;
+ }
+ }
+ }
+
+ /* fstrings are only allowed in Python 3.6 and greater */
+ if (fmode && c->c_feature_version < 6) {
+ ast_error(c, n, "Format strings are only supported in Python 3.6 and greater");
+ return -1;
+ }
+
+ if (fmode && *bytesmode) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ if (quote != '\'' && quote != '\"') {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ /* Skip the leading quote char. */
+ s++;
+ len = strlen(s);
+ if (len > INT_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "string to parse is too long");
+ return -1;
+ }
+ if (s[--len] != quote) {
+ /* Last quote char must match the first. */
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ if (len >= 4 && s[0] == quote && s[1] == quote) {
+ /* A triple quoted string. We've already skipped one quote at
+ the start and one at the end of the string. Now skip the
+ two at the start. */
+ s += 2;
+ len -= 2;
+ /* And check that the last two match. */
+ if (s[--len] != quote || s[--len] != quote) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ }
+
+ if (fmode) {
+ /* Just return the bytes. The caller will parse the resulting
+ string. */
+ *fstr = s;
+ *fstrlen = len;
+ return 0;
+ }
+
+ /* Not an f-string. */
+ /* Avoid invoking escape decoding routines if possible. */
+ *rawmode = *rawmode || strchr(s, '\\') == NULL;
+ if (*bytesmode) {
+ /* Disallow non-ASCII characters. */
+ const char *ch;
+ for (ch = s; *ch; ch++) {
+ if (Py_CHARMASK(*ch) >= 0x80) {
+ ast_error(c, n,
+ "bytes can only contain ASCII "
+ "literal characters.");
+ return -1;
+ }
+ }
+ if (*rawmode)
+ *result = PyBytes_FromStringAndSize(s, len);
+ else
+ *result = decode_bytes_with_escapes(c, n, s, len);
+ } else {
+ if (*rawmode)
+ *result = PyUnicode_DecodeUTF8Stateful(s, len, NULL, NULL);
+ else
+ *result = decode_unicode_with_escapes(c, n, s, len);
+ }
+ return *result == NULL ? -1 : 0;
+}
+
+/* Accepts a STRING+ atom, and produces an expr_ty node. Run through
+ each STRING atom, and process it as needed. For bytes, just
+ concatenate them together, and the result will be a Constant node. For
+ normal strings and f-strings, concatenate them together. The result
+ will be a Constant node if there were no f-strings; a FormattedValue
+ node if there's just an f-string (with no leading or trailing
+ literals), or a JoinedStr node if there are multiple f-strings or
+ any literals involved. */
+static expr_ty
+parsestrplus(struct compiling *c, const node *n)
+{
+ int bytesmode = 0;
+ PyObject *bytes_str = NULL;
+ int i;
+
+ FstringParser state;
+ FstringParser_Init(&state);
+
+ for (i = 0; i < NCH(n); i++) {
+ int this_bytesmode;
+ int this_rawmode;
+ PyObject *s;
+ const char *fstr;
+ Py_ssize_t fstrlen = -1; /* Silence a compiler warning. */
+
+ REQ(CHILD(n, i), STRING);
+ if (parsestr(c, CHILD(n, i), &this_bytesmode, &this_rawmode, &s,
+ &fstr, &fstrlen) != 0)
+ goto error;
+
+ /* Check that we're not mixing bytes with unicode. */
+ if (i != 0 && bytesmode != this_bytesmode) {
+ ast_error(c, n, "cannot mix bytes and nonbytes literals");
+ /* s is NULL if the current string part is an f-string. */
+ Py_XDECREF(s);
+ goto error;
+ }
+ bytesmode = this_bytesmode;
+
+ if (fstr != NULL) {
+ int result;
+ assert(s == NULL && !bytesmode);
+ /* This is an f-string. Parse and concatenate it. */
+ result = FstringParser_ConcatFstring(&state, &fstr, fstr+fstrlen,
+ this_rawmode, 0, c, n);
+ if (result < 0)
+ goto error;
+ } else {
+ /* A string or byte string. */
+ assert(s != NULL && fstr == NULL);
+
+ assert(bytesmode ? PyBytes_CheckExact(s) :
+ PyUnicode_CheckExact(s));
+
+ if (bytesmode) {
+ /* For bytes, concat as we go. */
+ if (i == 0) {
+ /* First time, just remember this value. */
+ bytes_str = s;
+ } else {
+ PyBytes_ConcatAndDel(&bytes_str, s);
+ if (!bytes_str)
+ goto error;
+ }
+ } else {
+ /* This is a regular string. Concatenate it. */
+ if (FstringParser_ConcatAndDel(&state, s) < 0)
+ goto error;
+ }
+ }
+ }
+ if (bytesmode) {
+ /* Just return the bytes object and we're done. */
+ if (PyArena_AddPyObject(c->c_arena, bytes_str) < 0)
+ goto error;
+ return Constant(bytes_str, NULL, LINENO(n), n->n_col_offset,
+ n->n_end_lineno, n->n_end_col_offset, c->c_arena);
+ }
+
+ /* We're not a bytes string, bytes_str should never have been set. */
+ assert(bytes_str == NULL);
+
+ return FstringParser_Finish(&state, c, n);
+
+error:
+ Py_XDECREF(bytes_str);
+ FstringParser_Dealloc(&state);
+ return NULL;
+}
+
+PyObject *
+_PyAST_GetDocString(asdl_seq *body)
+{
+ if (!asdl_seq_LEN(body)) {
+ return NULL;
+ }
+ stmt_ty st = (stmt_ty)asdl_seq_GET(body, 0);
+ if (st->kind != Expr_kind) {
+ return NULL;
+ }
+ expr_ty e = st->v.Expr.value;
+ if (e->kind == Constant_kind && PyUnicode_CheckExact(e->v.Constant.value)) {
+ return e->v.Constant.value;
+ }
+ return NULL;
+}
diff --git a/contrib/tools/python3/src/Python/ast_opt.c b/contrib/tools/python3/src/Python/ast_opt.c
new file mode 100644
index 00000000000..ff786d6f8d6
--- /dev/null
+++ b/contrib/tools/python3/src/Python/ast_opt.c
@@ -0,0 +1,752 @@
+/* AST Optimizer */
+#include "Python.h"
+#include "Python-ast.h"
+#include "ast.h"
+
+
+static int
+make_const(expr_ty node, PyObject *val, PyArena *arena)
+{
+ if (val == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) {
+ return 0;
+ }
+ PyErr_Clear();
+ return 1;
+ }
+ if (PyArena_AddPyObject(arena, val) < 0) {
+ Py_DECREF(val);
+ return 0;
+ }
+ node->kind = Constant_kind;
+ node->v.Constant.kind = NULL;
+ node->v.Constant.value = val;
+ return 1;
+}
+
+#define COPY_NODE(TO, FROM) (memcpy((TO), (FROM), sizeof(struct _expr)))
+
+static PyObject*
+unary_not(PyObject *v)
+{
+ int r = PyObject_IsTrue(v);
+ if (r < 0)
+ return NULL;
+ return PyBool_FromLong(!r);
+}
+
+static int
+fold_unaryop(expr_ty node, PyArena *arena, _PyASTOptimizeState *state)
+{
+ expr_ty arg = node->v.UnaryOp.operand;
+
+ if (arg->kind != Constant_kind) {
+ /* Fold not into comparison */
+ if (node->v.UnaryOp.op == Not && arg->kind == Compare_kind &&
+ asdl_seq_LEN(arg->v.Compare.ops) == 1) {
+ /* Eq and NotEq are often implemented in terms of one another, so
+ folding not (self == other) into self != other breaks implementation
+ of !=. Detecting such cases doesn't seem worthwhile.
+ Python uses </> for 'is subset'/'is superset' operations on sets.
+ They don't satisfy not folding laws. */
+ int op = asdl_seq_GET(arg->v.Compare.ops, 0);
+ switch (op) {
+ case Is:
+ op = IsNot;
+ break;
+ case IsNot:
+ op = Is;
+ break;
+ case In:
+ op = NotIn;
+ break;
+ case NotIn:
+ op = In;
+ break;
+ default:
+ op = 0;
+ }
+ if (op) {
+ asdl_seq_SET(arg->v.Compare.ops, 0, op);
+ COPY_NODE(node, arg);
+ return 1;
+ }
+ }
+ return 1;
+ }
+
+ typedef PyObject *(*unary_op)(PyObject*);
+ static const unary_op ops[] = {
+ [Invert] = PyNumber_Invert,
+ [Not] = unary_not,
+ [UAdd] = PyNumber_Positive,
+ [USub] = PyNumber_Negative,
+ };
+ PyObject *newval = ops[node->v.UnaryOp.op](arg->v.Constant.value);
+ return make_const(node, newval, arena);
+}
+
+/* Check whether a collection doesn't containing too much items (including
+ subcollections). This protects from creating a constant that needs
+ too much time for calculating a hash.
+ "limit" is the maximal number of items.
+ Returns the negative number if the total number of items exceeds the
+ limit. Otherwise returns the limit minus the total number of items.
+*/
+
+static Py_ssize_t
+check_complexity(PyObject *obj, Py_ssize_t limit)
+{
+ if (PyTuple_Check(obj)) {
+ Py_ssize_t i;
+ limit -= PyTuple_GET_SIZE(obj);
+ for (i = 0; limit >= 0 && i < PyTuple_GET_SIZE(obj); i++) {
+ limit = check_complexity(PyTuple_GET_ITEM(obj, i), limit);
+ }
+ return limit;
+ }
+ else if (PyFrozenSet_Check(obj)) {
+ Py_ssize_t i = 0;
+ PyObject *item;
+ Py_hash_t hash;
+ limit -= PySet_GET_SIZE(obj);
+ while (limit >= 0 && _PySet_NextEntry(obj, &i, &item, &hash)) {
+ limit = check_complexity(item, limit);
+ }
+ }
+ return limit;
+}
+
+#define MAX_INT_SIZE 128 /* bits */
+#define MAX_COLLECTION_SIZE 256 /* items */
+#define MAX_STR_SIZE 4096 /* characters */
+#define MAX_TOTAL_ITEMS 1024 /* including nested collections */
+
+static PyObject *
+safe_multiply(PyObject *v, PyObject *w)
+{
+ if (PyLong_Check(v) && PyLong_Check(w) && Py_SIZE(v) && Py_SIZE(w)) {
+ size_t vbits = _PyLong_NumBits(v);
+ size_t wbits = _PyLong_NumBits(w);
+ if (vbits == (size_t)-1 || wbits == (size_t)-1) {
+ return NULL;
+ }
+ if (vbits + wbits > MAX_INT_SIZE) {
+ return NULL;
+ }
+ }
+ else if (PyLong_Check(v) && (PyTuple_Check(w) || PyFrozenSet_Check(w))) {
+ Py_ssize_t size = PyTuple_Check(w) ? PyTuple_GET_SIZE(w) :
+ PySet_GET_SIZE(w);
+ if (size) {
+ long n = PyLong_AsLong(v);
+ if (n < 0 || n > MAX_COLLECTION_SIZE / size) {
+ return NULL;
+ }
+ if (n && check_complexity(w, MAX_TOTAL_ITEMS / n) < 0) {
+ return NULL;
+ }
+ }
+ }
+ else if (PyLong_Check(v) && (PyUnicode_Check(w) || PyBytes_Check(w))) {
+ Py_ssize_t size = PyUnicode_Check(w) ? PyUnicode_GET_LENGTH(w) :
+ PyBytes_GET_SIZE(w);
+ if (size) {
+ long n = PyLong_AsLong(v);
+ if (n < 0 || n > MAX_STR_SIZE / size) {
+ return NULL;
+ }
+ }
+ }
+ else if (PyLong_Check(w) &&
+ (PyTuple_Check(v) || PyFrozenSet_Check(v) ||
+ PyUnicode_Check(v) || PyBytes_Check(v)))
+ {
+ return safe_multiply(w, v);
+ }
+
+ return PyNumber_Multiply(v, w);
+}
+
+static PyObject *
+safe_power(PyObject *v, PyObject *w)
+{
+ if (PyLong_Check(v) && PyLong_Check(w) && Py_SIZE(v) && Py_SIZE(w) > 0) {
+ size_t vbits = _PyLong_NumBits(v);
+ size_t wbits = PyLong_AsSize_t(w);
+ if (vbits == (size_t)-1 || wbits == (size_t)-1) {
+ return NULL;
+ }
+ if (vbits > MAX_INT_SIZE / wbits) {
+ return NULL;
+ }
+ }
+
+ return PyNumber_Power(v, w, Py_None);
+}
+
+static PyObject *
+safe_lshift(PyObject *v, PyObject *w)
+{
+ if (PyLong_Check(v) && PyLong_Check(w) && Py_SIZE(v) && Py_SIZE(w)) {
+ size_t vbits = _PyLong_NumBits(v);
+ size_t wbits = PyLong_AsSize_t(w);
+ if (vbits == (size_t)-1 || wbits == (size_t)-1) {
+ return NULL;
+ }
+ if (wbits > MAX_INT_SIZE || vbits > MAX_INT_SIZE - wbits) {
+ return NULL;
+ }
+ }
+
+ return PyNumber_Lshift(v, w);
+}
+
+static PyObject *
+safe_mod(PyObject *v, PyObject *w)
+{
+ if (PyUnicode_Check(v) || PyBytes_Check(v)) {
+ return NULL;
+ }
+
+ return PyNumber_Remainder(v, w);
+}
+
+static int
+fold_binop(expr_ty node, PyArena *arena, _PyASTOptimizeState *state)
+{
+ expr_ty lhs, rhs;
+ lhs = node->v.BinOp.left;
+ rhs = node->v.BinOp.right;
+ if (lhs->kind != Constant_kind || rhs->kind != Constant_kind) {
+ return 1;
+ }
+
+ PyObject *lv = lhs->v.Constant.value;
+ PyObject *rv = rhs->v.Constant.value;
+ PyObject *newval;
+
+ switch (node->v.BinOp.op) {
+ case Add:
+ newval = PyNumber_Add(lv, rv);
+ break;
+ case Sub:
+ newval = PyNumber_Subtract(lv, rv);
+ break;
+ case Mult:
+ newval = safe_multiply(lv, rv);
+ break;
+ case Div:
+ newval = PyNumber_TrueDivide(lv, rv);
+ break;
+ case FloorDiv:
+ newval = PyNumber_FloorDivide(lv, rv);
+ break;
+ case Mod:
+ newval = safe_mod(lv, rv);
+ break;
+ case Pow:
+ newval = safe_power(lv, rv);
+ break;
+ case LShift:
+ newval = safe_lshift(lv, rv);
+ break;
+ case RShift:
+ newval = PyNumber_Rshift(lv, rv);
+ break;
+ case BitOr:
+ newval = PyNumber_Or(lv, rv);
+ break;
+ case BitXor:
+ newval = PyNumber_Xor(lv, rv);
+ break;
+ case BitAnd:
+ newval = PyNumber_And(lv, rv);
+ break;
+ default: // Unknown operator
+ return 1;
+ }
+
+ return make_const(node, newval, arena);
+}
+
+static PyObject*
+make_const_tuple(asdl_seq *elts)
+{
+ for (int i = 0; i < asdl_seq_LEN(elts); i++) {
+ expr_ty e = (expr_ty)asdl_seq_GET(elts, i);
+ if (e->kind != Constant_kind) {
+ return NULL;
+ }
+ }
+
+ PyObject *newval = PyTuple_New(asdl_seq_LEN(elts));
+ if (newval == NULL) {
+ return NULL;
+ }
+
+ for (int i = 0; i < asdl_seq_LEN(elts); i++) {
+ expr_ty e = (expr_ty)asdl_seq_GET(elts, i);
+ PyObject *v = e->v.Constant.value;
+ Py_INCREF(v);
+ PyTuple_SET_ITEM(newval, i, v);
+ }
+ return newval;
+}
+
+static int
+fold_tuple(expr_ty node, PyArena *arena, _PyASTOptimizeState *state)
+{
+ PyObject *newval;
+
+ if (node->v.Tuple.ctx != Load)
+ return 1;
+
+ newval = make_const_tuple(node->v.Tuple.elts);
+ return make_const(node, newval, arena);
+}
+
+static int
+fold_subscr(expr_ty node, PyArena *arena, _PyASTOptimizeState *state)
+{
+ PyObject *newval;
+ expr_ty arg, idx;
+
+ arg = node->v.Subscript.value;
+ idx = node->v.Subscript.slice;
+ if (node->v.Subscript.ctx != Load ||
+ arg->kind != Constant_kind ||
+ idx->kind != Constant_kind)
+ {
+ return 1;
+ }
+
+ newval = PyObject_GetItem(arg->v.Constant.value, idx->v.Constant.value);
+ return make_const(node, newval, arena);
+}
+
+/* Change literal list or set of constants into constant
+ tuple or frozenset respectively. Change literal list of
+ non-constants into tuple.
+ Used for right operand of "in" and "not in" tests and for iterable
+ in "for" loop and comprehensions.
+*/
+static int
+fold_iter(expr_ty arg, PyArena *arena, _PyASTOptimizeState *state)
+{
+ PyObject *newval;
+ if (arg->kind == List_kind) {
+ /* First change a list into tuple. */
+ asdl_seq *elts = arg->v.List.elts;
+ Py_ssize_t n = asdl_seq_LEN(elts);
+ for (Py_ssize_t i = 0; i < n; i++) {
+ expr_ty e = (expr_ty)asdl_seq_GET(elts, i);
+ if (e->kind == Starred_kind) {
+ return 1;
+ }
+ }
+ expr_context_ty ctx = arg->v.List.ctx;
+ arg->kind = Tuple_kind;
+ arg->v.Tuple.elts = elts;
+ arg->v.Tuple.ctx = ctx;
+ /* Try to create a constant tuple. */
+ newval = make_const_tuple(elts);
+ }
+ else if (arg->kind == Set_kind) {
+ newval = make_const_tuple(arg->v.Set.elts);
+ if (newval) {
+ Py_SETREF(newval, PyFrozenSet_New(newval));
+ }
+ }
+ else {
+ return 1;
+ }
+ return make_const(arg, newval, arena);
+}
+
+static int
+fold_compare(expr_ty node, PyArena *arena, _PyASTOptimizeState *state)
+{
+ asdl_int_seq *ops;
+ asdl_seq *args;
+ Py_ssize_t i;
+
+ ops = node->v.Compare.ops;
+ args = node->v.Compare.comparators;
+ /* TODO: optimize cases with literal arguments. */
+ /* Change literal list or set in 'in' or 'not in' into
+ tuple or frozenset respectively. */
+ i = asdl_seq_LEN(ops) - 1;
+ int op = asdl_seq_GET(ops, i);
+ if (op == In || op == NotIn) {
+ if (!fold_iter((expr_ty)asdl_seq_GET(args, i), arena, state)) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int astfold_mod(mod_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
+static int astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
+static int astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
+static int astfold_arguments(arguments_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
+static int astfold_comprehension(comprehension_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
+static int astfold_keyword(keyword_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
+static int astfold_arg(arg_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
+static int astfold_withitem(withitem_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
+static int astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
+#define CALL(FUNC, TYPE, ARG) \
+ if (!FUNC((ARG), ctx_, state)) \
+ return 0;
+
+#define CALL_OPT(FUNC, TYPE, ARG) \
+ if ((ARG) != NULL && !FUNC((ARG), ctx_, state)) \
+ return 0;
+
+#define CALL_SEQ(FUNC, TYPE, ARG) { \
+ int i; \
+ asdl_seq *seq = (ARG); /* avoid variable capture */ \
+ for (i = 0; i < asdl_seq_LEN(seq); i++) { \
+ TYPE elt = (TYPE)asdl_seq_GET(seq, i); \
+ if (elt != NULL && !FUNC(elt, ctx_, state)) \
+ return 0; \
+ } \
+}
+
+#define CALL_INT_SEQ(FUNC, TYPE, ARG) { \
+ int i; \
+ asdl_int_seq *seq = (ARG); /* avoid variable capture */ \
+ for (i = 0; i < asdl_seq_LEN(seq); i++) { \
+ TYPE elt = (TYPE)asdl_seq_GET(seq, i); \
+ if (!FUNC(elt, ctx_, state)) \
+ return 0; \
+ } \
+}
+
+static int
+astfold_body(asdl_seq *stmts, PyArena *ctx_, _PyASTOptimizeState *state)
+{
+ int docstring = _PyAST_GetDocString(stmts) != NULL;
+ CALL_SEQ(astfold_stmt, stmt_ty, stmts);
+ if (!docstring && _PyAST_GetDocString(stmts) != NULL) {
+ stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0);
+ asdl_seq *values = _Py_asdl_seq_new(1, ctx_);
+ if (!values) {
+ return 0;
+ }
+ asdl_seq_SET(values, 0, st->v.Expr.value);
+ expr_ty expr = JoinedStr(values, st->lineno, st->col_offset,
+ st->end_lineno, st->end_col_offset, ctx_);
+ if (!expr) {
+ return 0;
+ }
+ st->v.Expr.value = expr;
+ }
+ return 1;
+}
+
+static int
+astfold_mod(mod_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
+{
+ switch (node_->kind) {
+ case Module_kind:
+ CALL(astfold_body, asdl_seq, node_->v.Module.body);
+ break;
+ case Interactive_kind:
+ CALL_SEQ(astfold_stmt, stmt_ty, node_->v.Interactive.body);
+ break;
+ case Expression_kind:
+ CALL(astfold_expr, expr_ty, node_->v.Expression.body);
+ break;
+ default:
+ break;
+ }
+ return 1;
+}
+
+static int
+astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
+{
+ switch (node_->kind) {
+ case BoolOp_kind:
+ CALL_SEQ(astfold_expr, expr_ty, node_->v.BoolOp.values);
+ break;
+ case BinOp_kind:
+ CALL(astfold_expr, expr_ty, node_->v.BinOp.left);
+ CALL(astfold_expr, expr_ty, node_->v.BinOp.right);
+ CALL(fold_binop, expr_ty, node_);
+ break;
+ case UnaryOp_kind:
+ CALL(astfold_expr, expr_ty, node_->v.UnaryOp.operand);
+ CALL(fold_unaryop, expr_ty, node_);
+ break;
+ case Lambda_kind:
+ CALL(astfold_arguments, arguments_ty, node_->v.Lambda.args);
+ CALL(astfold_expr, expr_ty, node_->v.Lambda.body);
+ break;
+ case IfExp_kind:
+ CALL(astfold_expr, expr_ty, node_->v.IfExp.test);
+ CALL(astfold_expr, expr_ty, node_->v.IfExp.body);
+ CALL(astfold_expr, expr_ty, node_->v.IfExp.orelse);
+ break;
+ case Dict_kind:
+ CALL_SEQ(astfold_expr, expr_ty, node_->v.Dict.keys);
+ CALL_SEQ(astfold_expr, expr_ty, node_->v.Dict.values);
+ break;
+ case Set_kind:
+ CALL_SEQ(astfold_expr, expr_ty, node_->v.Set.elts);
+ break;
+ case ListComp_kind:
+ CALL(astfold_expr, expr_ty, node_->v.ListComp.elt);
+ CALL_SEQ(astfold_comprehension, comprehension_ty, node_->v.ListComp.generators);
+ break;
+ case SetComp_kind:
+ CALL(astfold_expr, expr_ty, node_->v.SetComp.elt);
+ CALL_SEQ(astfold_comprehension, comprehension_ty, node_->v.SetComp.generators);
+ break;
+ case DictComp_kind:
+ CALL(astfold_expr, expr_ty, node_->v.DictComp.key);
+ CALL(astfold_expr, expr_ty, node_->v.DictComp.value);
+ CALL_SEQ(astfold_comprehension, comprehension_ty, node_->v.DictComp.generators);
+ break;
+ case GeneratorExp_kind:
+ CALL(astfold_expr, expr_ty, node_->v.GeneratorExp.elt);
+ CALL_SEQ(astfold_comprehension, comprehension_ty, node_->v.GeneratorExp.generators);
+ break;
+ case Await_kind:
+ CALL(astfold_expr, expr_ty, node_->v.Await.value);
+ break;
+ case Yield_kind:
+ CALL_OPT(astfold_expr, expr_ty, node_->v.Yield.value);
+ break;
+ case YieldFrom_kind:
+ CALL(astfold_expr, expr_ty, node_->v.YieldFrom.value);
+ break;
+ case Compare_kind:
+ CALL(astfold_expr, expr_ty, node_->v.Compare.left);
+ CALL_SEQ(astfold_expr, expr_ty, node_->v.Compare.comparators);
+ CALL(fold_compare, expr_ty, node_);
+ break;
+ case Call_kind:
+ CALL(astfold_expr, expr_ty, node_->v.Call.func);
+ CALL_SEQ(astfold_expr, expr_ty, node_->v.Call.args);
+ CALL_SEQ(astfold_keyword, keyword_ty, node_->v.Call.keywords);
+ break;
+ case FormattedValue_kind:
+ CALL(astfold_expr, expr_ty, node_->v.FormattedValue.value);
+ CALL_OPT(astfold_expr, expr_ty, node_->v.FormattedValue.format_spec);
+ break;
+ case JoinedStr_kind:
+ CALL_SEQ(astfold_expr, expr_ty, node_->v.JoinedStr.values);
+ break;
+ case Attribute_kind:
+ CALL(astfold_expr, expr_ty, node_->v.Attribute.value);
+ break;
+ case Subscript_kind:
+ CALL(astfold_expr, expr_ty, node_->v.Subscript.value);
+ CALL(astfold_expr, expr_ty, node_->v.Subscript.slice);
+ CALL(fold_subscr, expr_ty, node_);
+ break;
+ case Starred_kind:
+ CALL(astfold_expr, expr_ty, node_->v.Starred.value);
+ break;
+ case Slice_kind:
+ CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.lower);
+ CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.upper);
+ CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.step);
+ break;
+ case List_kind:
+ CALL_SEQ(astfold_expr, expr_ty, node_->v.List.elts);
+ break;
+ case Tuple_kind:
+ CALL_SEQ(astfold_expr, expr_ty, node_->v.Tuple.elts);
+ CALL(fold_tuple, expr_ty, node_);
+ break;
+ case Name_kind:
+ if (node_->v.Name.ctx == Load &&
+ _PyUnicode_EqualToASCIIString(node_->v.Name.id, "__debug__")) {
+ return make_const(node_, PyBool_FromLong(!state->optimize), ctx_);
+ }
+ break;
+ default:
+ break;
+ }
+ return 1;
+}
+
+static int
+astfold_keyword(keyword_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
+{
+ CALL(astfold_expr, expr_ty, node_->value);
+ return 1;
+}
+
+static int
+astfold_comprehension(comprehension_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
+{
+ CALL(astfold_expr, expr_ty, node_->target);
+ CALL(astfold_expr, expr_ty, node_->iter);
+ CALL_SEQ(astfold_expr, expr_ty, node_->ifs);
+
+ CALL(fold_iter, expr_ty, node_->iter);
+ return 1;
+}
+
+static int
+astfold_arguments(arguments_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
+{
+ CALL_SEQ(astfold_arg, arg_ty, node_->posonlyargs);
+ CALL_SEQ(astfold_arg, arg_ty, node_->args);
+ CALL_OPT(astfold_arg, arg_ty, node_->vararg);
+ CALL_SEQ(astfold_arg, arg_ty, node_->kwonlyargs);
+ CALL_SEQ(astfold_expr, expr_ty, node_->kw_defaults);
+ CALL_OPT(astfold_arg, arg_ty, node_->kwarg);
+ CALL_SEQ(astfold_expr, expr_ty, node_->defaults);
+ return 1;
+}
+
+static int
+astfold_arg(arg_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
+{
+ if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) {
+ CALL_OPT(astfold_expr, expr_ty, node_->annotation);
+ }
+ return 1;
+}
+
+static int
+astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
+{
+ switch (node_->kind) {
+ case FunctionDef_kind:
+ CALL(astfold_arguments, arguments_ty, node_->v.FunctionDef.args);
+ CALL(astfold_body, asdl_seq, node_->v.FunctionDef.body);
+ CALL_SEQ(astfold_expr, expr_ty, node_->v.FunctionDef.decorator_list);
+ if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) {
+ CALL_OPT(astfold_expr, expr_ty, node_->v.FunctionDef.returns);
+ }
+ break;
+ case AsyncFunctionDef_kind:
+ CALL(astfold_arguments, arguments_ty, node_->v.AsyncFunctionDef.args);
+ CALL(astfold_body, asdl_seq, node_->v.AsyncFunctionDef.body);
+ CALL_SEQ(astfold_expr, expr_ty, node_->v.AsyncFunctionDef.decorator_list);
+ if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) {
+ CALL_OPT(astfold_expr, expr_ty, node_->v.AsyncFunctionDef.returns);
+ }
+ break;
+ case ClassDef_kind:
+ CALL_SEQ(astfold_expr, expr_ty, node_->v.ClassDef.bases);
+ CALL_SEQ(astfold_keyword, keyword_ty, node_->v.ClassDef.keywords);
+ CALL(astfold_body, asdl_seq, node_->v.ClassDef.body);
+ CALL_SEQ(astfold_expr, expr_ty, node_->v.ClassDef.decorator_list);
+ break;
+ case Return_kind:
+ CALL_OPT(astfold_expr, expr_ty, node_->v.Return.value);
+ break;
+ case Delete_kind:
+ CALL_SEQ(astfold_expr, expr_ty, node_->v.Delete.targets);
+ break;
+ case Assign_kind:
+ CALL_SEQ(astfold_expr, expr_ty, node_->v.Assign.targets);
+ CALL(astfold_expr, expr_ty, node_->v.Assign.value);
+ break;
+ case AugAssign_kind:
+ CALL(astfold_expr, expr_ty, node_->v.AugAssign.target);
+ CALL(astfold_expr, expr_ty, node_->v.AugAssign.value);
+ break;
+ case AnnAssign_kind:
+ CALL(astfold_expr, expr_ty, node_->v.AnnAssign.target);
+ if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) {
+ CALL(astfold_expr, expr_ty, node_->v.AnnAssign.annotation);
+ }
+ CALL_OPT(astfold_expr, expr_ty, node_->v.AnnAssign.value);
+ break;
+ case For_kind:
+ CALL(astfold_expr, expr_ty, node_->v.For.target);
+ CALL(astfold_expr, expr_ty, node_->v.For.iter);
+ CALL_SEQ(astfold_stmt, stmt_ty, node_->v.For.body);
+ CALL_SEQ(astfold_stmt, stmt_ty, node_->v.For.orelse);
+
+ CALL(fold_iter, expr_ty, node_->v.For.iter);
+ break;
+ case AsyncFor_kind:
+ CALL(astfold_expr, expr_ty, node_->v.AsyncFor.target);
+ CALL(astfold_expr, expr_ty, node_->v.AsyncFor.iter);
+ CALL_SEQ(astfold_stmt, stmt_ty, node_->v.AsyncFor.body);
+ CALL_SEQ(astfold_stmt, stmt_ty, node_->v.AsyncFor.orelse);
+ break;
+ case While_kind:
+ CALL(astfold_expr, expr_ty, node_->v.While.test);
+ CALL_SEQ(astfold_stmt, stmt_ty, node_->v.While.body);
+ CALL_SEQ(astfold_stmt, stmt_ty, node_->v.While.orelse);
+ break;
+ case If_kind:
+ CALL(astfold_expr, expr_ty, node_->v.If.test);
+ CALL_SEQ(astfold_stmt, stmt_ty, node_->v.If.body);
+ CALL_SEQ(astfold_stmt, stmt_ty, node_->v.If.orelse);
+ break;
+ case With_kind:
+ CALL_SEQ(astfold_withitem, withitem_ty, node_->v.With.items);
+ CALL_SEQ(astfold_stmt, stmt_ty, node_->v.With.body);
+ break;
+ case AsyncWith_kind:
+ CALL_SEQ(astfold_withitem, withitem_ty, node_->v.AsyncWith.items);
+ CALL_SEQ(astfold_stmt, stmt_ty, node_->v.AsyncWith.body);
+ break;
+ case Raise_kind:
+ CALL_OPT(astfold_expr, expr_ty, node_->v.Raise.exc);
+ CALL_OPT(astfold_expr, expr_ty, node_->v.Raise.cause);
+ break;
+ case Try_kind:
+ CALL_SEQ(astfold_stmt, stmt_ty, node_->v.Try.body);
+ CALL_SEQ(astfold_excepthandler, excepthandler_ty, node_->v.Try.handlers);
+ CALL_SEQ(astfold_stmt, stmt_ty, node_->v.Try.orelse);
+ CALL_SEQ(astfold_stmt, stmt_ty, node_->v.Try.finalbody);
+ break;
+ case Assert_kind:
+ CALL(astfold_expr, expr_ty, node_->v.Assert.test);
+ CALL_OPT(astfold_expr, expr_ty, node_->v.Assert.msg);
+ break;
+ case Expr_kind:
+ CALL(astfold_expr, expr_ty, node_->v.Expr.value);
+ break;
+ default:
+ break;
+ }
+ return 1;
+}
+
+static int
+astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
+{
+ switch (node_->kind) {
+ case ExceptHandler_kind:
+ CALL_OPT(astfold_expr, expr_ty, node_->v.ExceptHandler.type);
+ CALL_SEQ(astfold_stmt, stmt_ty, node_->v.ExceptHandler.body);
+ break;
+ default:
+ break;
+ }
+ return 1;
+}
+
+static int
+astfold_withitem(withitem_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
+{
+ CALL(astfold_expr, expr_ty, node_->context_expr);
+ CALL_OPT(astfold_expr, expr_ty, node_->optional_vars);
+ return 1;
+}
+
+#undef CALL
+#undef CALL_OPT
+#undef CALL_SEQ
+#undef CALL_INT_SEQ
+
+int
+_PyAST_Optimize(mod_ty mod, PyArena *arena, _PyASTOptimizeState *state)
+{
+ int ret = astfold_mod(mod, arena, state);
+ assert(ret || PyErr_Occurred());
+ return ret;
+}
diff --git a/contrib/tools/python3/src/Python/ast_unparse.c b/contrib/tools/python3/src/Python/ast_unparse.c
new file mode 100644
index 00000000000..e699751a05a
--- /dev/null
+++ b/contrib/tools/python3/src/Python/ast_unparse.c
@@ -0,0 +1,972 @@
+#include <float.h> /* DBL_MAX_10_EXP */
+#include <stdbool.h>
+#include "Python.h"
+#include "Python-ast.h"
+
+static PyObject *_str_open_br;
+static PyObject *_str_dbl_open_br;
+static PyObject *_str_close_br;
+static PyObject *_str_dbl_close_br;
+static PyObject *_str_inf;
+static PyObject *_str_replace_inf;
+
+/* Forward declarations for recursion via helper functions. */
+static PyObject *
+expr_as_unicode(expr_ty e, int level);
+static int
+append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, int level);
+static int
+append_joinedstr(_PyUnicodeWriter *writer, expr_ty e, bool is_format_spec);
+static int
+append_formattedvalue(_PyUnicodeWriter *writer, expr_ty e);
+static int
+append_ast_slice(_PyUnicodeWriter *writer, expr_ty e);
+
+static int
+append_charp(_PyUnicodeWriter *writer, const char *charp)
+{
+ return _PyUnicodeWriter_WriteASCIIString(writer, charp, -1);
+}
+
+#define APPEND_STR_FINISH(str) do { \
+ return append_charp(writer, (str)); \
+ } while (0)
+
+#define APPEND_STR(str) do { \
+ if (-1 == append_charp(writer, (str))) { \
+ return -1; \
+ } \
+ } while (0)
+
+#define APPEND_STR_IF(cond, str) do { \
+ if ((cond) && -1 == append_charp(writer, (str))) { \
+ return -1; \
+ } \
+ } while (0)
+
+#define APPEND_STR_IF_NOT_FIRST(str) do { \
+ APPEND_STR_IF(!first, (str)); \
+ first = false; \
+ } while (0)
+
+#define APPEND_EXPR(expr, pr) do { \
+ if (-1 == append_ast_expr(writer, (expr), (pr))) { \
+ return -1; \
+ } \
+ } while (0)
+
+#define APPEND(type, value) do { \
+ if (-1 == append_ast_ ## type(writer, (value))) { \
+ return -1; \
+ } \
+ } while (0)
+
+static int
+append_repr(_PyUnicodeWriter *writer, PyObject *obj)
+{
+ PyObject *repr = PyObject_Repr(obj);
+
+ if (!repr) {
+ return -1;
+ }
+
+ if ((PyFloat_CheckExact(obj) && Py_IS_INFINITY(PyFloat_AS_DOUBLE(obj))) ||
+ PyComplex_CheckExact(obj))
+ {
+ PyObject *new_repr = PyUnicode_Replace(
+ repr,
+ _str_inf,
+ _str_replace_inf,
+ -1
+ );
+ Py_DECREF(repr);
+ if (!new_repr) {
+ return -1;
+ }
+ repr = new_repr;
+ }
+ int ret = _PyUnicodeWriter_WriteStr(writer, repr);
+ Py_DECREF(repr);
+ return ret;
+}
+
+/* Priority levels */
+
+enum {
+ PR_TUPLE,
+ PR_TEST, /* 'if'-'else', 'lambda' */
+ PR_OR, /* 'or' */
+ PR_AND, /* 'and' */
+ PR_NOT, /* 'not' */
+ PR_CMP, /* '<', '>', '==', '>=', '<=', '!=',
+ 'in', 'not in', 'is', 'is not' */
+ PR_EXPR,
+ PR_BOR = PR_EXPR, /* '|' */
+ PR_BXOR, /* '^' */
+ PR_BAND, /* '&' */
+ PR_SHIFT, /* '<<', '>>' */
+ PR_ARITH, /* '+', '-' */
+ PR_TERM, /* '*', '@', '/', '%', '//' */
+ PR_FACTOR, /* unary '+', '-', '~' */
+ PR_POWER, /* '**' */
+ PR_AWAIT, /* 'await' */
+ PR_ATOM,
+};
+
+static int
+append_ast_boolop(_PyUnicodeWriter *writer, expr_ty e, int level)
+{
+ Py_ssize_t i, value_count;
+ asdl_seq *values;
+ const char *op = (e->v.BoolOp.op == And) ? " and " : " or ";
+ int pr = (e->v.BoolOp.op == And) ? PR_AND : PR_OR;
+
+ APPEND_STR_IF(level > pr, "(");
+
+ values = e->v.BoolOp.values;
+ value_count = asdl_seq_LEN(values);
+
+ for (i = 0; i < value_count; ++i) {
+ APPEND_STR_IF(i > 0, op);
+ APPEND_EXPR((expr_ty)asdl_seq_GET(values, i), pr + 1);
+ }
+
+ APPEND_STR_IF(level > pr, ")");
+ return 0;
+}
+
+static int
+append_ast_binop(_PyUnicodeWriter *writer, expr_ty e, int level)
+{
+ const char *op;
+ int pr;
+ bool rassoc = false; /* is right-associative? */
+
+ switch (e->v.BinOp.op) {
+ case Add: op = " + "; pr = PR_ARITH; break;
+ case Sub: op = " - "; pr = PR_ARITH; break;
+ case Mult: op = " * "; pr = PR_TERM; break;
+ case MatMult: op = " @ "; pr = PR_TERM; break;
+ case Div: op = " / "; pr = PR_TERM; break;
+ case Mod: op = " % "; pr = PR_TERM; break;
+ case LShift: op = " << "; pr = PR_SHIFT; break;
+ case RShift: op = " >> "; pr = PR_SHIFT; break;
+ case BitOr: op = " | "; pr = PR_BOR; break;
+ case BitXor: op = " ^ "; pr = PR_BXOR; break;
+ case BitAnd: op = " & "; pr = PR_BAND; break;
+ case FloorDiv: op = " // "; pr = PR_TERM; break;
+ case Pow: op = " ** "; pr = PR_POWER; rassoc = true; break;
+ default:
+ PyErr_SetString(PyExc_SystemError,
+ "unknown binary operator");
+ return -1;
+ }
+
+ APPEND_STR_IF(level > pr, "(");
+ APPEND_EXPR(e->v.BinOp.left, pr + rassoc);
+ APPEND_STR(op);
+ APPEND_EXPR(e->v.BinOp.right, pr + !rassoc);
+ APPEND_STR_IF(level > pr, ")");
+ return 0;
+}
+
+static int
+append_ast_unaryop(_PyUnicodeWriter *writer, expr_ty e, int level)
+{
+ const char *op;
+ int pr;
+
+ switch (e->v.UnaryOp.op) {
+ case Invert: op = "~"; pr = PR_FACTOR; break;
+ case Not: op = "not "; pr = PR_NOT; break;
+ case UAdd: op = "+"; pr = PR_FACTOR; break;
+ case USub: op = "-"; pr = PR_FACTOR; break;
+ default:
+ PyErr_SetString(PyExc_SystemError,
+ "unknown unary operator");
+ return -1;
+ }
+
+ APPEND_STR_IF(level > pr, "(");
+ APPEND_STR(op);
+ APPEND_EXPR(e->v.UnaryOp.operand, pr);
+ APPEND_STR_IF(level > pr, ")");
+ return 0;
+}
+
+static int
+append_ast_arg(_PyUnicodeWriter *writer, arg_ty arg)
+{
+ if (-1 == _PyUnicodeWriter_WriteStr(writer, arg->arg)) {
+ return -1;
+ }
+ if (arg->annotation) {
+ APPEND_STR(": ");
+ APPEND_EXPR(arg->annotation, PR_TEST);
+ }
+ return 0;
+}
+
+static int
+append_ast_args(_PyUnicodeWriter *writer, arguments_ty args)
+{
+ bool first;
+ Py_ssize_t i, di, arg_count, posonlyarg_count, default_count;
+
+ first = true;
+
+ /* positional-only and positional arguments with defaults */
+ posonlyarg_count = asdl_seq_LEN(args->posonlyargs);
+ arg_count = asdl_seq_LEN(args->args);
+ default_count = asdl_seq_LEN(args->defaults);
+ for (i = 0; i < posonlyarg_count + arg_count; i++) {
+ APPEND_STR_IF_NOT_FIRST(", ");
+ if (i < posonlyarg_count){
+ APPEND(arg, (arg_ty)asdl_seq_GET(args->posonlyargs, i));
+ } else {
+ APPEND(arg, (arg_ty)asdl_seq_GET(args->args, i-posonlyarg_count));
+ }
+
+ di = i - posonlyarg_count - arg_count + default_count;
+ if (di >= 0) {
+ APPEND_STR("=");
+ APPEND_EXPR((expr_ty)asdl_seq_GET(args->defaults, di), PR_TEST);
+ }
+ if (posonlyarg_count && i + 1 == posonlyarg_count) {
+ APPEND_STR(", /");
+ }
+ }
+
+ /* vararg, or bare '*' if no varargs but keyword-only arguments present */
+ if (args->vararg || asdl_seq_LEN(args->kwonlyargs)) {
+ APPEND_STR_IF_NOT_FIRST(", ");
+ APPEND_STR("*");
+ if (args->vararg) {
+ APPEND(arg, args->vararg);
+ }
+ }
+
+ /* keyword-only arguments */
+ arg_count = asdl_seq_LEN(args->kwonlyargs);
+ default_count = asdl_seq_LEN(args->kw_defaults);
+ for (i = 0; i < arg_count; i++) {
+ APPEND_STR_IF_NOT_FIRST(", ");
+ APPEND(arg, (arg_ty)asdl_seq_GET(args->kwonlyargs, i));
+
+ di = i - arg_count + default_count;
+ if (di >= 0) {
+ expr_ty default_ = (expr_ty)asdl_seq_GET(args->kw_defaults, di);
+ if (default_) {
+ APPEND_STR("=");
+ APPEND_EXPR(default_, PR_TEST);
+ }
+ }
+ }
+
+ /* **kwargs */
+ if (args->kwarg) {
+ APPEND_STR_IF_NOT_FIRST(", ");
+ APPEND_STR("**");
+ APPEND(arg, args->kwarg);
+ }
+
+ return 0;
+}
+
+static int
+append_ast_lambda(_PyUnicodeWriter *writer, expr_ty e, int level)
+{
+ APPEND_STR_IF(level > PR_TEST, "(");
+ Py_ssize_t n_positional = (asdl_seq_LEN(e->v.Lambda.args->args) +
+ asdl_seq_LEN(e->v.Lambda.args->posonlyargs));
+ APPEND_STR(n_positional ? "lambda " : "lambda");
+ APPEND(args, e->v.Lambda.args);
+ APPEND_STR(": ");
+ APPEND_EXPR(e->v.Lambda.body, PR_TEST);
+ APPEND_STR_IF(level > PR_TEST, ")");
+ return 0;
+}
+
+static int
+append_ast_ifexp(_PyUnicodeWriter *writer, expr_ty e, int level)
+{
+ APPEND_STR_IF(level > PR_TEST, "(");
+ APPEND_EXPR(e->v.IfExp.body, PR_TEST + 1);
+ APPEND_STR(" if ");
+ APPEND_EXPR(e->v.IfExp.test, PR_TEST + 1);
+ APPEND_STR(" else ");
+ APPEND_EXPR(e->v.IfExp.orelse, PR_TEST);
+ APPEND_STR_IF(level > PR_TEST, ")");
+ return 0;
+}
+
+static int
+append_ast_dict(_PyUnicodeWriter *writer, expr_ty e)
+{
+ Py_ssize_t i, value_count;
+ expr_ty key_node;
+
+ APPEND_STR("{");
+ value_count = asdl_seq_LEN(e->v.Dict.values);
+
+ for (i = 0; i < value_count; i++) {
+ APPEND_STR_IF(i > 0, ", ");
+ key_node = (expr_ty)asdl_seq_GET(e->v.Dict.keys, i);
+ if (key_node != NULL) {
+ APPEND_EXPR(key_node, PR_TEST);
+ APPEND_STR(": ");
+ APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.Dict.values, i), PR_TEST);
+ }
+ else {
+ APPEND_STR("**");
+ APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.Dict.values, i), PR_EXPR);
+ }
+ }
+
+ APPEND_STR_FINISH("}");
+}
+
+static int
+append_ast_set(_PyUnicodeWriter *writer, expr_ty e)
+{
+ Py_ssize_t i, elem_count;
+
+ APPEND_STR("{");
+ elem_count = asdl_seq_LEN(e->v.Set.elts);
+ for (i = 0; i < elem_count; i++) {
+ APPEND_STR_IF(i > 0, ", ");
+ APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.Set.elts, i), PR_TEST);
+ }
+
+ APPEND_STR_FINISH("}");
+}
+
+static int
+append_ast_list(_PyUnicodeWriter *writer, expr_ty e)
+{
+ Py_ssize_t i, elem_count;
+
+ APPEND_STR("[");
+ elem_count = asdl_seq_LEN(e->v.List.elts);
+ for (i = 0; i < elem_count; i++) {
+ APPEND_STR_IF(i > 0, ", ");
+ APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.List.elts, i), PR_TEST);
+ }
+
+ APPEND_STR_FINISH("]");
+}
+
+static int
+append_ast_tuple(_PyUnicodeWriter *writer, expr_ty e, int level)
+{
+ Py_ssize_t i, elem_count;
+
+ elem_count = asdl_seq_LEN(e->v.Tuple.elts);
+
+ if (elem_count == 0) {
+ APPEND_STR_FINISH("()");
+ }
+
+ APPEND_STR_IF(level > PR_TUPLE, "(");
+
+ for (i = 0; i < elem_count; i++) {
+ APPEND_STR_IF(i > 0, ", ");
+ APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.Tuple.elts, i), PR_TEST);
+ }
+
+ APPEND_STR_IF(elem_count == 1, ",");
+ APPEND_STR_IF(level > PR_TUPLE, ")");
+ return 0;
+}
+
+static int
+append_ast_comprehension(_PyUnicodeWriter *writer, comprehension_ty gen)
+{
+ Py_ssize_t i, if_count;
+
+ APPEND_STR(gen->is_async ? " async for " : " for ");
+ APPEND_EXPR(gen->target, PR_TUPLE);
+ APPEND_STR(" in ");
+ APPEND_EXPR(gen->iter, PR_TEST + 1);
+
+ if_count = asdl_seq_LEN(gen->ifs);
+ for (i = 0; i < if_count; i++) {
+ APPEND_STR(" if ");
+ APPEND_EXPR((expr_ty)asdl_seq_GET(gen->ifs, i), PR_TEST + 1);
+ }
+ return 0;
+}
+
+static int
+append_ast_comprehensions(_PyUnicodeWriter *writer, asdl_seq *comprehensions)
+{
+ Py_ssize_t i, gen_count;
+ gen_count = asdl_seq_LEN(comprehensions);
+
+ for (i = 0; i < gen_count; i++) {
+ APPEND(comprehension, (comprehension_ty)asdl_seq_GET(comprehensions, i));
+ }
+
+ return 0;
+}
+
+static int
+append_ast_genexp(_PyUnicodeWriter *writer, expr_ty e)
+{
+ APPEND_STR("(");
+ APPEND_EXPR(e->v.GeneratorExp.elt, PR_TEST);
+ APPEND(comprehensions, e->v.GeneratorExp.generators);
+ APPEND_STR_FINISH(")");
+}
+
+static int
+append_ast_listcomp(_PyUnicodeWriter *writer, expr_ty e)
+{
+ APPEND_STR("[");
+ APPEND_EXPR(e->v.ListComp.elt, PR_TEST);
+ APPEND(comprehensions, e->v.ListComp.generators);
+ APPEND_STR_FINISH("]");
+}
+
+static int
+append_ast_setcomp(_PyUnicodeWriter *writer, expr_ty e)
+{
+ APPEND_STR("{");
+ APPEND_EXPR(e->v.SetComp.elt, PR_TEST);
+ APPEND(comprehensions, e->v.SetComp.generators);
+ APPEND_STR_FINISH("}");
+}
+
+static int
+append_ast_dictcomp(_PyUnicodeWriter *writer, expr_ty e)
+{
+ APPEND_STR("{");
+ APPEND_EXPR(e->v.DictComp.key, PR_TEST);
+ APPEND_STR(": ");
+ APPEND_EXPR(e->v.DictComp.value, PR_TEST);
+ APPEND(comprehensions, e->v.DictComp.generators);
+ APPEND_STR_FINISH("}");
+}
+
+static int
+append_ast_compare(_PyUnicodeWriter *writer, expr_ty e, int level)
+{
+ const char *op;
+ Py_ssize_t i, comparator_count;
+ asdl_seq *comparators;
+ asdl_int_seq *ops;
+
+ APPEND_STR_IF(level > PR_CMP, "(");
+
+ comparators = e->v.Compare.comparators;
+ ops = e->v.Compare.ops;
+ comparator_count = asdl_seq_LEN(comparators);
+ assert(comparator_count > 0);
+ assert(comparator_count == asdl_seq_LEN(ops));
+
+ APPEND_EXPR(e->v.Compare.left, PR_CMP + 1);
+
+ for (i = 0; i < comparator_count; i++) {
+ switch ((cmpop_ty)asdl_seq_GET(ops, i)) {
+ case Eq:
+ op = " == ";
+ break;
+ case NotEq:
+ op = " != ";
+ break;
+ case Lt:
+ op = " < ";
+ break;
+ case LtE:
+ op = " <= ";
+ break;
+ case Gt:
+ op = " > ";
+ break;
+ case GtE:
+ op = " >= ";
+ break;
+ case Is:
+ op = " is ";
+ break;
+ case IsNot:
+ op = " is not ";
+ break;
+ case In:
+ op = " in ";
+ break;
+ case NotIn:
+ op = " not in ";
+ break;
+ default:
+ PyErr_SetString(PyExc_SystemError,
+ "unexpected comparison kind");
+ return -1;
+ }
+
+ APPEND_STR(op);
+ APPEND_EXPR((expr_ty)asdl_seq_GET(comparators, i), PR_CMP + 1);
+ }
+
+ APPEND_STR_IF(level > PR_CMP, ")");
+ return 0;
+}
+
+static int
+append_ast_keyword(_PyUnicodeWriter *writer, keyword_ty kw)
+{
+ if (kw->arg == NULL) {
+ APPEND_STR("**");
+ }
+ else {
+ if (-1 == _PyUnicodeWriter_WriteStr(writer, kw->arg)) {
+ return -1;
+ }
+
+ APPEND_STR("=");
+ }
+
+ APPEND_EXPR(kw->value, PR_TEST);
+ return 0;
+}
+
+static int
+append_ast_call(_PyUnicodeWriter *writer, expr_ty e)
+{
+ bool first;
+ Py_ssize_t i, arg_count, kw_count;
+ expr_ty expr;
+
+ APPEND_EXPR(e->v.Call.func, PR_ATOM);
+
+ arg_count = asdl_seq_LEN(e->v.Call.args);
+ kw_count = asdl_seq_LEN(e->v.Call.keywords);
+ if (arg_count == 1 && kw_count == 0) {
+ expr = (expr_ty)asdl_seq_GET(e->v.Call.args, 0);
+ if (expr->kind == GeneratorExp_kind) {
+ /* Special case: a single generator expression. */
+ return append_ast_genexp(writer, expr);
+ }
+ }
+
+ APPEND_STR("(");
+
+ first = true;
+ for (i = 0; i < arg_count; i++) {
+ APPEND_STR_IF_NOT_FIRST(", ");
+ APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.Call.args, i), PR_TEST);
+ }
+
+ for (i = 0; i < kw_count; i++) {
+ APPEND_STR_IF_NOT_FIRST(", ");
+ APPEND(keyword, (keyword_ty)asdl_seq_GET(e->v.Call.keywords, i));
+ }
+
+ APPEND_STR_FINISH(")");
+}
+
+static PyObject *
+escape_braces(PyObject *orig)
+{
+ PyObject *temp;
+ PyObject *result;
+ temp = PyUnicode_Replace(orig, _str_open_br, _str_dbl_open_br, -1);
+ if (!temp) {
+ return NULL;
+ }
+ result = PyUnicode_Replace(temp, _str_close_br, _str_dbl_close_br, -1);
+ Py_DECREF(temp);
+ return result;
+}
+
+static int
+append_fstring_unicode(_PyUnicodeWriter *writer, PyObject *unicode)
+{
+ PyObject *escaped;
+ int result = -1;
+ escaped = escape_braces(unicode);
+ if (escaped) {
+ result = _PyUnicodeWriter_WriteStr(writer, escaped);
+ Py_DECREF(escaped);
+ }
+ return result;
+}
+
+static int
+append_fstring_element(_PyUnicodeWriter *writer, expr_ty e, bool is_format_spec)
+{
+ switch (e->kind) {
+ case Constant_kind:
+ return append_fstring_unicode(writer, e->v.Constant.value);
+ case JoinedStr_kind:
+ return append_joinedstr(writer, e, is_format_spec);
+ case FormattedValue_kind:
+ return append_formattedvalue(writer, e);
+ default:
+ PyErr_SetString(PyExc_SystemError,
+ "unknown expression kind inside f-string");
+ return -1;
+ }
+}
+
+/* Build body separately to enable wrapping the entire stream of Strs,
+ Constants and FormattedValues in one opening and one closing quote. */
+static PyObject *
+build_fstring_body(asdl_seq *values, bool is_format_spec)
+{
+ Py_ssize_t i, value_count;
+ _PyUnicodeWriter body_writer;
+ _PyUnicodeWriter_Init(&body_writer);
+ body_writer.min_length = 256;
+ body_writer.overallocate = 1;
+
+ value_count = asdl_seq_LEN(values);
+ for (i = 0; i < value_count; ++i) {
+ if (-1 == append_fstring_element(&body_writer,
+ (expr_ty)asdl_seq_GET(values, i),
+ is_format_spec
+ )) {
+ _PyUnicodeWriter_Dealloc(&body_writer);
+ return NULL;
+ }
+ }
+
+ return _PyUnicodeWriter_Finish(&body_writer);
+}
+
+static int
+append_joinedstr(_PyUnicodeWriter *writer, expr_ty e, bool is_format_spec)
+{
+ int result = -1;
+ PyObject *body = build_fstring_body(e->v.JoinedStr.values, is_format_spec);
+ if (!body) {
+ return -1;
+ }
+
+ if (!is_format_spec) {
+ if (-1 != append_charp(writer, "f") &&
+ -1 != append_repr(writer, body))
+ {
+ result = 0;
+ }
+ }
+ else {
+ result = _PyUnicodeWriter_WriteStr(writer, body);
+ }
+ Py_DECREF(body);
+ return result;
+}
+
+static int
+append_formattedvalue(_PyUnicodeWriter *writer, expr_ty e)
+{
+ const char *conversion;
+ const char *outer_brace = "{";
+ /* Grammar allows PR_TUPLE, but use >PR_TEST for adding parenthesis
+ around a lambda with ':' */
+ PyObject *temp_fv_str = expr_as_unicode(e->v.FormattedValue.value, PR_TEST + 1);
+ if (!temp_fv_str) {
+ return -1;
+ }
+ if (PyUnicode_Find(temp_fv_str, _str_open_br, 0, 1, 1) == 0) {
+ /* Expression starts with a brace, split it with a space from the outer
+ one. */
+ outer_brace = "{ ";
+ }
+ if (-1 == append_charp(writer, outer_brace)) {
+ Py_DECREF(temp_fv_str);
+ return -1;
+ }
+ if (-1 == _PyUnicodeWriter_WriteStr(writer, temp_fv_str)) {
+ Py_DECREF(temp_fv_str);
+ return -1;
+ }
+ Py_DECREF(temp_fv_str);
+
+ if (e->v.FormattedValue.conversion > 0) {
+ switch (e->v.FormattedValue.conversion) {
+ case 'a':
+ conversion = "!a";
+ break;
+ case 'r':
+ conversion = "!r";
+ break;
+ case 's':
+ conversion = "!s";
+ break;
+ default:
+ PyErr_SetString(PyExc_SystemError,
+ "unknown f-value conversion kind");
+ return -1;
+ }
+ APPEND_STR(conversion);
+ }
+ if (e->v.FormattedValue.format_spec) {
+ if (-1 == _PyUnicodeWriter_WriteASCIIString(writer, ":", 1) ||
+ -1 == append_fstring_element(writer,
+ e->v.FormattedValue.format_spec,
+ true
+ ))
+ {
+ return -1;
+ }
+ }
+
+ APPEND_STR_FINISH("}");
+}
+
+static int
+append_ast_constant(_PyUnicodeWriter *writer, PyObject *constant)
+{
+ if (PyTuple_CheckExact(constant)) {
+ Py_ssize_t i, elem_count;
+
+ elem_count = PyTuple_GET_SIZE(constant);
+ APPEND_STR("(");
+ for (i = 0; i < elem_count; i++) {
+ APPEND_STR_IF(i > 0, ", ");
+ if (append_ast_constant(writer, PyTuple_GET_ITEM(constant, i)) < 0) {
+ return -1;
+ }
+ }
+
+ APPEND_STR_IF(elem_count == 1, ",");
+ APPEND_STR(")");
+ return 0;
+ }
+ return append_repr(writer, constant);
+}
+
+static int
+append_ast_attribute(_PyUnicodeWriter *writer, expr_ty e)
+{
+ const char *period;
+ expr_ty v = e->v.Attribute.value;
+ APPEND_EXPR(v, PR_ATOM);
+
+ /* Special case: integers require a space for attribute access to be
+ unambiguous. */
+ if (v->kind == Constant_kind && PyLong_CheckExact(v->v.Constant.value)) {
+ period = " .";
+ }
+ else {
+ period = ".";
+ }
+ APPEND_STR(period);
+
+ return _PyUnicodeWriter_WriteStr(writer, e->v.Attribute.attr);
+}
+
+static int
+append_ast_slice(_PyUnicodeWriter *writer, expr_ty e)
+{
+ if (e->v.Slice.lower) {
+ APPEND_EXPR(e->v.Slice.lower, PR_TEST);
+ }
+
+ APPEND_STR(":");
+
+ if (e->v.Slice.upper) {
+ APPEND_EXPR(e->v.Slice.upper, PR_TEST);
+ }
+
+ if (e->v.Slice.step) {
+ APPEND_STR(":");
+ APPEND_EXPR(e->v.Slice.step, PR_TEST);
+ }
+ return 0;
+}
+
+static int
+append_ast_subscript(_PyUnicodeWriter *writer, expr_ty e)
+{
+ APPEND_EXPR(e->v.Subscript.value, PR_ATOM);
+ int level = PR_TUPLE;
+ expr_ty slice = e->v.Subscript.slice;
+ if (slice->kind == Tuple_kind) {
+ for (Py_ssize_t i = 0; i < asdl_seq_LEN(slice->v.Tuple.elts); i++) {
+ expr_ty element = asdl_seq_GET(slice->v.Tuple.elts, i);
+ if (element->kind == Starred_kind) {
+ ++level;
+ break;
+ }
+ }
+ }
+ APPEND_STR("[");
+ APPEND_EXPR(e->v.Subscript.slice, level);
+ APPEND_STR_FINISH("]");
+}
+
+static int
+append_ast_starred(_PyUnicodeWriter *writer, expr_ty e)
+{
+ APPEND_STR("*");
+ APPEND_EXPR(e->v.Starred.value, PR_EXPR);
+ return 0;
+}
+
+static int
+append_ast_yield(_PyUnicodeWriter *writer, expr_ty e)
+{
+ if (!e->v.Yield.value) {
+ APPEND_STR_FINISH("(yield)");
+ }
+
+ APPEND_STR("(yield ");
+ APPEND_EXPR(e->v.Yield.value, PR_TEST);
+ APPEND_STR_FINISH(")");
+}
+
+static int
+append_ast_yield_from(_PyUnicodeWriter *writer, expr_ty e)
+{
+ APPEND_STR("(yield from ");
+ APPEND_EXPR(e->v.YieldFrom.value, PR_TEST);
+ APPEND_STR_FINISH(")");
+}
+
+static int
+append_ast_await(_PyUnicodeWriter *writer, expr_ty e, int level)
+{
+ APPEND_STR_IF(level > PR_AWAIT, "(");
+ APPEND_STR("await ");
+ APPEND_EXPR(e->v.Await.value, PR_ATOM);
+ APPEND_STR_IF(level > PR_AWAIT, ")");
+ return 0;
+}
+
+static int
+append_named_expr(_PyUnicodeWriter *writer, expr_ty e, int level)
+{
+ APPEND_STR_IF(level > PR_TUPLE, "(");
+ APPEND_EXPR(e->v.NamedExpr.target, PR_ATOM);
+ APPEND_STR(" := ");
+ APPEND_EXPR(e->v.NamedExpr.value, PR_ATOM);
+ APPEND_STR_IF(level > PR_TUPLE, ")");
+ return 0;
+}
+
+static int
+append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, int level)
+{
+ switch (e->kind) {
+ case BoolOp_kind:
+ return append_ast_boolop(writer, e, level);
+ case BinOp_kind:
+ return append_ast_binop(writer, e, level);
+ case UnaryOp_kind:
+ return append_ast_unaryop(writer, e, level);
+ case Lambda_kind:
+ return append_ast_lambda(writer, e, level);
+ case IfExp_kind:
+ return append_ast_ifexp(writer, e, level);
+ case Dict_kind:
+ return append_ast_dict(writer, e);
+ case Set_kind:
+ return append_ast_set(writer, e);
+ case GeneratorExp_kind:
+ return append_ast_genexp(writer, e);
+ case ListComp_kind:
+ return append_ast_listcomp(writer, e);
+ case SetComp_kind:
+ return append_ast_setcomp(writer, e);
+ case DictComp_kind:
+ return append_ast_dictcomp(writer, e);
+ case Yield_kind:
+ return append_ast_yield(writer, e);
+ case YieldFrom_kind:
+ return append_ast_yield_from(writer, e);
+ case Await_kind:
+ return append_ast_await(writer, e, level);
+ case Compare_kind:
+ return append_ast_compare(writer, e, level);
+ case Call_kind:
+ return append_ast_call(writer, e);
+ case Constant_kind:
+ if (e->v.Constant.value == Py_Ellipsis) {
+ APPEND_STR_FINISH("...");
+ }
+ if (e->v.Constant.kind != NULL
+ && -1 == _PyUnicodeWriter_WriteStr(writer, e->v.Constant.kind)) {
+ return -1;
+ }
+ return append_ast_constant(writer, e->v.Constant.value);
+ case JoinedStr_kind:
+ return append_joinedstr(writer, e, false);
+ case FormattedValue_kind:
+ return append_formattedvalue(writer, e);
+ /* The following exprs can be assignment targets. */
+ case Attribute_kind:
+ return append_ast_attribute(writer, e);
+ case Subscript_kind:
+ return append_ast_subscript(writer, e);
+ case Starred_kind:
+ return append_ast_starred(writer, e);
+ case Slice_kind:
+ return append_ast_slice(writer, e);
+ case Name_kind:
+ return _PyUnicodeWriter_WriteStr(writer, e->v.Name.id);
+ case List_kind:
+ return append_ast_list(writer, e);
+ case Tuple_kind:
+ return append_ast_tuple(writer, e, level);
+ case NamedExpr_kind:
+ return append_named_expr(writer, e, level);
+ default:
+ PyErr_SetString(PyExc_SystemError,
+ "unknown expression kind");
+ return -1;
+ }
+}
+
+static int
+maybe_init_static_strings(void)
+{
+ if (!_str_open_br &&
+ !(_str_open_br = PyUnicode_InternFromString("{"))) {
+ return -1;
+ }
+ if (!_str_dbl_open_br &&
+ !(_str_dbl_open_br = PyUnicode_InternFromString("{{"))) {
+ return -1;
+ }
+ if (!_str_close_br &&
+ !(_str_close_br = PyUnicode_InternFromString("}"))) {
+ return -1;
+ }
+ if (!_str_dbl_close_br &&
+ !(_str_dbl_close_br = PyUnicode_InternFromString("}}"))) {
+ return -1;
+ }
+ if (!_str_inf &&
+ !(_str_inf = PyUnicode_FromString("inf"))) {
+ return -1;
+ }
+ if (!_str_replace_inf &&
+ !(_str_replace_inf = PyUnicode_FromFormat("1e%d", 1 + DBL_MAX_10_EXP))) {
+ return -1;
+ }
+ return 0;
+}
+
+static PyObject *
+expr_as_unicode(expr_ty e, int level)
+{
+ _PyUnicodeWriter writer;
+ _PyUnicodeWriter_Init(&writer);
+ writer.min_length = 256;
+ writer.overallocate = 1;
+ if (-1 == maybe_init_static_strings() ||
+ -1 == append_ast_expr(&writer, e, level))
+ {
+ _PyUnicodeWriter_Dealloc(&writer);
+ return NULL;
+ }
+ return _PyUnicodeWriter_Finish(&writer);
+}
+
+PyObject *
+_PyAST_ExprAsUnicode(expr_ty e)
+{
+ return expr_as_unicode(e, PR_TEST);
+}
diff --git a/contrib/tools/python3/src/Python/bltinmodule.c b/contrib/tools/python3/src/Python/bltinmodule.c
new file mode 100644
index 00000000000..21c70f9a6c7
--- /dev/null
+++ b/contrib/tools/python3/src/Python/bltinmodule.c
@@ -0,0 +1,2843 @@
+/* Built-in functions */
+
+#include "Python.h"
+#include <ctype.h>
+#include "ast.h"
+#undef Yield /* undefine macro conflicting with <winbase.h> */
+#include "pycore_object.h"
+#include "pycore_pyerrors.h"
+#include "pycore_pystate.h" // _PyThreadState_GET()
+#include "pycore_tupleobject.h"
+
+_Py_IDENTIFIER(__builtins__);
+_Py_IDENTIFIER(__dict__);
+_Py_IDENTIFIER(__prepare__);
+_Py_IDENTIFIER(__round__);
+_Py_IDENTIFIER(__mro_entries__);
+_Py_IDENTIFIER(encoding);
+_Py_IDENTIFIER(errors);
+_Py_IDENTIFIER(fileno);
+_Py_IDENTIFIER(flush);
+_Py_IDENTIFIER(metaclass);
+_Py_IDENTIFIER(sort);
+_Py_IDENTIFIER(stdin);
+_Py_IDENTIFIER(stdout);
+_Py_IDENTIFIER(stderr);
+
+#include "clinic/bltinmodule.c.h"
+
+static PyObject*
+update_bases(PyObject *bases, PyObject *const *args, Py_ssize_t nargs)
+{
+ Py_ssize_t i, j;
+ PyObject *base, *meth, *new_base, *result, *new_bases = NULL;
+ assert(PyTuple_Check(bases));
+
+ for (i = 0; i < nargs; i++) {
+ base = args[i];
+ if (PyType_Check(base)) {
+ if (new_bases) {
+ /* If we already have made a replacement, then we append every normal base,
+ otherwise just skip it. */
+ if (PyList_Append(new_bases, base) < 0) {
+ goto error;
+ }
+ }
+ continue;
+ }
+ if (_PyObject_LookupAttrId(base, &PyId___mro_entries__, &meth) < 0) {
+ goto error;
+ }
+ if (!meth) {
+ if (new_bases) {
+ if (PyList_Append(new_bases, base) < 0) {
+ goto error;
+ }
+ }
+ continue;
+ }
+ new_base = PyObject_CallOneArg(meth, bases);
+ Py_DECREF(meth);
+ if (!new_base) {
+ goto error;
+ }
+ if (!PyTuple_Check(new_base)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__mro_entries__ must return a tuple");
+ Py_DECREF(new_base);
+ goto error;
+ }
+ if (!new_bases) {
+ /* If this is a first successful replacement, create new_bases list and
+ copy previously encountered bases. */
+ if (!(new_bases = PyList_New(i))) {
+ Py_DECREF(new_base);
+ goto error;
+ }
+ for (j = 0; j < i; j++) {
+ base = args[j];
+ PyList_SET_ITEM(new_bases, j, base);
+ Py_INCREF(base);
+ }
+ }
+ j = PyList_GET_SIZE(new_bases);
+ if (PyList_SetSlice(new_bases, j, j, new_base) < 0) {
+ Py_DECREF(new_base);
+ goto error;
+ }
+ Py_DECREF(new_base);
+ }
+ if (!new_bases) {
+ return bases;
+ }
+ result = PyList_AsTuple(new_bases);
+ Py_DECREF(new_bases);
+ return result;
+
+error:
+ Py_XDECREF(new_bases);
+ return NULL;
+}
+
+/* AC: cannot convert yet, waiting for *args support */
+static PyObject *
+builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
+ PyObject *kwnames)
+{
+ PyObject *func, *name, *winner, *prep;
+ PyObject *cls = NULL, *cell = NULL, *ns = NULL, *meta = NULL, *orig_bases = NULL;
+ PyObject *mkw = NULL, *bases = NULL;
+ int isclass = 0; /* initialize to prevent gcc warning */
+
+ if (nargs < 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "__build_class__: not enough arguments");
+ return NULL;
+ }
+ func = args[0]; /* Better be callable */
+ if (!PyFunction_Check(func)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__build_class__: func must be a function");
+ return NULL;
+ }
+ name = args[1];
+ if (!PyUnicode_Check(name)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__build_class__: name is not a string");
+ return NULL;
+ }
+ orig_bases = _PyTuple_FromArray(args + 2, nargs - 2);
+ if (orig_bases == NULL)
+ return NULL;
+
+ bases = update_bases(orig_bases, args + 2, nargs - 2);
+ if (bases == NULL) {
+ Py_DECREF(orig_bases);
+ return NULL;
+ }
+
+ if (kwnames == NULL) {
+ meta = NULL;
+ mkw = NULL;
+ }
+ else {
+ mkw = _PyStack_AsDict(args + nargs, kwnames);
+ if (mkw == NULL) {
+ goto error;
+ }
+
+ meta = _PyDict_GetItemIdWithError(mkw, &PyId_metaclass);
+ if (meta != NULL) {
+ Py_INCREF(meta);
+ if (_PyDict_DelItemId(mkw, &PyId_metaclass) < 0) {
+ goto error;
+ }
+ /* metaclass is explicitly given, check if it's indeed a class */
+ isclass = PyType_Check(meta);
+ }
+ else if (PyErr_Occurred()) {
+ goto error;
+ }
+ }
+ if (meta == NULL) {
+ /* if there are no bases, use type: */
+ if (PyTuple_GET_SIZE(bases) == 0) {
+ meta = (PyObject *) (&PyType_Type);
+ }
+ /* else get the type of the first base */
+ else {
+ PyObject *base0 = PyTuple_GET_ITEM(bases, 0);
+ meta = (PyObject *)Py_TYPE(base0);
+ }
+ Py_INCREF(meta);
+ isclass = 1; /* meta is really a class */
+ }
+
+ if (isclass) {
+ /* meta is really a class, so check for a more derived
+ metaclass, or possible metaclass conflicts: */
+ winner = (PyObject *)_PyType_CalculateMetaclass((PyTypeObject *)meta,
+ bases);
+ if (winner == NULL) {
+ goto error;
+ }
+ if (winner != meta) {
+ Py_DECREF(meta);
+ meta = winner;
+ Py_INCREF(meta);
+ }
+ }
+ /* else: meta is not a class, so we cannot do the metaclass
+ calculation, so we will use the explicitly given object as it is */
+ if (_PyObject_LookupAttrId(meta, &PyId___prepare__, &prep) < 0) {
+ ns = NULL;
+ }
+ else if (prep == NULL) {
+ ns = PyDict_New();
+ }
+ else {
+ PyObject *pargs[2] = {name, bases};
+ ns = PyObject_VectorcallDict(prep, pargs, 2, mkw);
+ Py_DECREF(prep);
+ }
+ if (ns == NULL) {
+ goto error;
+ }
+ if (!PyMapping_Check(ns)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s.__prepare__() must return a mapping, not %.200s",
+ isclass ? ((PyTypeObject *)meta)->tp_name : "<metaclass>",
+ Py_TYPE(ns)->tp_name);
+ goto error;
+ }
+ cell = PyEval_EvalCodeEx(PyFunction_GET_CODE(func), PyFunction_GET_GLOBALS(func), ns,
+ NULL, 0, NULL, 0, NULL, 0, NULL,
+ PyFunction_GET_CLOSURE(func));
+ if (cell != NULL) {
+ if (bases != orig_bases) {
+ if (PyMapping_SetItemString(ns, "__orig_bases__", orig_bases) < 0) {
+ goto error;
+ }
+ }
+ PyObject *margs[3] = {name, bases, ns};
+ cls = PyObject_VectorcallDict(meta, margs, 3, mkw);
+ if (cls != NULL && PyType_Check(cls) && PyCell_Check(cell)) {
+ PyObject *cell_cls = PyCell_GET(cell);
+ if (cell_cls != cls) {
+ if (cell_cls == NULL) {
+ const char *msg =
+ "__class__ not set defining %.200R as %.200R. "
+ "Was __classcell__ propagated to type.__new__?";
+ PyErr_Format(PyExc_RuntimeError, msg, name, cls);
+ } else {
+ const char *msg =
+ "__class__ set to %.200R defining %.200R as %.200R";
+ PyErr_Format(PyExc_TypeError, msg, cell_cls, name, cls);
+ }
+ Py_DECREF(cls);
+ cls = NULL;
+ goto error;
+ }
+ }
+ }
+error:
+ Py_XDECREF(cell);
+ Py_XDECREF(ns);
+ Py_XDECREF(meta);
+ Py_XDECREF(mkw);
+ if (bases != orig_bases) {
+ Py_DECREF(orig_bases);
+ }
+ Py_DECREF(bases);
+ return cls;
+}
+
+PyDoc_STRVAR(build_class_doc,
+"__build_class__(func, name, /, *bases, [metaclass], **kwds) -> class\n\
+\n\
+Internal helper function used by the class statement.");
+
+static PyObject *
+builtin___import__(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"name", "globals", "locals", "fromlist",
+ "level", 0};
+ PyObject *name, *globals = NULL, *locals = NULL, *fromlist = NULL;
+ int level = 0;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "U|OOOi:__import__",
+ kwlist, &name, &globals, &locals, &fromlist, &level))
+ return NULL;
+ return PyImport_ImportModuleLevelObject(name, globals, locals,
+ fromlist, level);
+}
+
+PyDoc_STRVAR(import_doc,
+"__import__(name, globals=None, locals=None, fromlist=(), level=0) -> module\n\
+\n\
+Import a module. Because this function is meant for use by the Python\n\
+interpreter and not for general use, it is better to use\n\
+importlib.import_module() to programmatically import a module.\n\
+\n\
+The globals argument is only used to determine the context;\n\
+they are not modified. The locals argument is unused. The fromlist\n\
+should be a list of names to emulate ``from name import ...'', or an\n\
+empty list to emulate ``import name''.\n\
+When importing a module from a package, note that __import__('A.B', ...)\n\
+returns package A when fromlist is empty, but its submodule B when\n\
+fromlist is not empty. The level argument is used to determine whether to\n\
+perform absolute or relative imports: 0 is absolute, while a positive number\n\
+is the number of parent directories to search relative to the current module.");
+
+
+/*[clinic input]
+abs as builtin_abs
+
+ x: object
+ /
+
+Return the absolute value of the argument.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_abs(PyObject *module, PyObject *x)
+/*[clinic end generated code: output=b1b433b9e51356f5 input=bed4ca14e29c20d1]*/
+{
+ return PyNumber_Absolute(x);
+}
+
+/*[clinic input]
+all as builtin_all
+
+ iterable: object
+ /
+
+Return True if bool(x) is True for all values x in the iterable.
+
+If the iterable is empty, return True.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_all(PyObject *module, PyObject *iterable)
+/*[clinic end generated code: output=ca2a7127276f79b3 input=1a7c5d1bc3438a21]*/
+{
+ PyObject *it, *item;
+ PyObject *(*iternext)(PyObject *);
+ int cmp;
+
+ it = PyObject_GetIter(iterable);
+ if (it == NULL)
+ return NULL;
+ iternext = *Py_TYPE(it)->tp_iternext;
+
+ for (;;) {
+ item = iternext(it);
+ if (item == NULL)
+ break;
+ cmp = PyObject_IsTrue(item);
+ Py_DECREF(item);
+ if (cmp < 0) {
+ Py_DECREF(it);
+ return NULL;
+ }
+ if (cmp == 0) {
+ Py_DECREF(it);
+ Py_RETURN_FALSE;
+ }
+ }
+ Py_DECREF(it);
+ if (PyErr_Occurred()) {
+ if (PyErr_ExceptionMatches(PyExc_StopIteration))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ Py_RETURN_TRUE;
+}
+
+/*[clinic input]
+any as builtin_any
+
+ iterable: object
+ /
+
+Return True if bool(x) is True for any x in the iterable.
+
+If the iterable is empty, return False.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_any(PyObject *module, PyObject *iterable)
+/*[clinic end generated code: output=fa65684748caa60e input=41d7451c23384f24]*/
+{
+ PyObject *it, *item;
+ PyObject *(*iternext)(PyObject *);
+ int cmp;
+
+ it = PyObject_GetIter(iterable);
+ if (it == NULL)
+ return NULL;
+ iternext = *Py_TYPE(it)->tp_iternext;
+
+ for (;;) {
+ item = iternext(it);
+ if (item == NULL)
+ break;
+ cmp = PyObject_IsTrue(item);
+ Py_DECREF(item);
+ if (cmp < 0) {
+ Py_DECREF(it);
+ return NULL;
+ }
+ if (cmp > 0) {
+ Py_DECREF(it);
+ Py_RETURN_TRUE;
+ }
+ }
+ Py_DECREF(it);
+ if (PyErr_Occurred()) {
+ if (PyErr_ExceptionMatches(PyExc_StopIteration))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ Py_RETURN_FALSE;
+}
+
+/*[clinic input]
+ascii as builtin_ascii
+
+ obj: object
+ /
+
+Return an ASCII-only representation of an object.
+
+As repr(), return a string containing a printable representation of an
+object, but escape the non-ASCII characters in the string returned by
+repr() using \\x, \\u or \\U escapes. This generates a string similar
+to that returned by repr() in Python 2.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_ascii(PyObject *module, PyObject *obj)
+/*[clinic end generated code: output=6d37b3f0984c7eb9 input=4c62732e1b3a3cc9]*/
+{
+ return PyObject_ASCII(obj);
+}
+
+
+/*[clinic input]
+bin as builtin_bin
+
+ number: object
+ /
+
+Return the binary representation of an integer.
+
+ >>> bin(2796202)
+ '0b1010101010101010101010'
+[clinic start generated code]*/
+
+static PyObject *
+builtin_bin(PyObject *module, PyObject *number)
+/*[clinic end generated code: output=b6fc4ad5e649f4f7 input=53f8a0264bacaf90]*/
+{
+ return PyNumber_ToBase(number, 2);
+}
+
+
+/*[clinic input]
+callable as builtin_callable
+
+ obj: object
+ /
+
+Return whether the object is callable (i.e., some kind of function).
+
+Note that classes are callable, as are instances of classes with a
+__call__() method.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_callable(PyObject *module, PyObject *obj)
+/*[clinic end generated code: output=2b095d59d934cb7e input=1423bab99cc41f58]*/
+{
+ return PyBool_FromLong((long)PyCallable_Check(obj));
+}
+
+static PyObject *
+builtin_breakpoint(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords)
+{
+ PyObject *hook = PySys_GetObject("breakpointhook");
+
+ if (hook == NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "lost sys.breakpointhook");
+ return NULL;
+ }
+
+ if (PySys_Audit("builtins.breakpoint", "O", hook) < 0) {
+ return NULL;
+ }
+
+ Py_INCREF(hook);
+ PyObject *retval = PyObject_Vectorcall(hook, args, nargs, keywords);
+ Py_DECREF(hook);
+ return retval;
+}
+
+PyDoc_STRVAR(breakpoint_doc,
+"breakpoint(*args, **kws)\n\
+\n\
+Call sys.breakpointhook(*args, **kws). sys.breakpointhook() must accept\n\
+whatever arguments are passed.\n\
+\n\
+By default, this drops you into the pdb debugger.");
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *func;
+ PyObject *it;
+} filterobject;
+
+static PyObject *
+filter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *func, *seq;
+ PyObject *it;
+ filterobject *lz;
+
+ if (type == &PyFilter_Type && !_PyArg_NoKeywords("filter", kwds))
+ return NULL;
+
+ if (!PyArg_UnpackTuple(args, "filter", 2, 2, &func, &seq))
+ return NULL;
+
+ /* Get iterator. */
+ it = PyObject_GetIter(seq);
+ if (it == NULL)
+ return NULL;
+
+ /* create filterobject structure */
+ lz = (filterobject *)type->tp_alloc(type, 0);
+ if (lz == NULL) {
+ Py_DECREF(it);
+ return NULL;
+ }
+ Py_INCREF(func);
+ lz->func = func;
+ lz->it = it;
+
+ return (PyObject *)lz;
+}
+
+static void
+filter_dealloc(filterobject *lz)
+{
+ PyObject_GC_UnTrack(lz);
+ Py_XDECREF(lz->func);
+ Py_XDECREF(lz->it);
+ Py_TYPE(lz)->tp_free(lz);
+}
+
+static int
+filter_traverse(filterobject *lz, visitproc visit, void *arg)
+{
+ Py_VISIT(lz->it);
+ Py_VISIT(lz->func);
+ return 0;
+}
+
+static PyObject *
+filter_next(filterobject *lz)
+{
+ PyObject *item;
+ PyObject *it = lz->it;
+ long ok;
+ PyObject *(*iternext)(PyObject *);
+ int checktrue = lz->func == Py_None || lz->func == (PyObject *)&PyBool_Type;
+
+ iternext = *Py_TYPE(it)->tp_iternext;
+ for (;;) {
+ item = iternext(it);
+ if (item == NULL)
+ return NULL;
+
+ if (checktrue) {
+ ok = PyObject_IsTrue(item);
+ } else {
+ PyObject *good;
+ good = PyObject_CallOneArg(lz->func, item);
+ if (good == NULL) {
+ Py_DECREF(item);
+ return NULL;
+ }
+ ok = PyObject_IsTrue(good);
+ Py_DECREF(good);
+ }
+ if (ok > 0)
+ return item;
+ Py_DECREF(item);
+ if (ok < 0)
+ return NULL;
+ }
+}
+
+static PyObject *
+filter_reduce(filterobject *lz, PyObject *Py_UNUSED(ignored))
+{
+ return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it);
+}
+
+PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
+
+static PyMethodDef filter_methods[] = {
+ {"__reduce__", (PyCFunction)filter_reduce, METH_NOARGS, reduce_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+PyDoc_STRVAR(filter_doc,
+"filter(function or None, iterable) --> filter object\n\
+\n\
+Return an iterator yielding those items of iterable for which function(item)\n\
+is true. If function is None, return the items that are true.");
+
+PyTypeObject PyFilter_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "filter", /* tp_name */
+ sizeof(filterobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)filter_dealloc, /* tp_dealloc */
+ 0, /* tp_vectorcall_offset */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_as_async */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ filter_doc, /* tp_doc */
+ (traverseproc)filter_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)filter_next, /* tp_iternext */
+ filter_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ filter_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+
+/*[clinic input]
+format as builtin_format
+
+ value: object
+ format_spec: unicode(c_default="NULL") = ''
+ /
+
+Return value.__format__(format_spec)
+
+format_spec defaults to the empty string.
+See the Format Specification Mini-Language section of help('FORMATTING') for
+details.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_format_impl(PyObject *module, PyObject *value, PyObject *format_spec)
+/*[clinic end generated code: output=2f40bdfa4954b077 input=88339c93ea522b33]*/
+{
+ return PyObject_Format(value, format_spec);
+}
+
+/*[clinic input]
+chr as builtin_chr
+
+ i: int
+ /
+
+Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_chr_impl(PyObject *module, int i)
+/*[clinic end generated code: output=c733afcd200afcb7 input=3f604ef45a70750d]*/
+{
+ return PyUnicode_FromOrdinal(i);
+}
+
+
+/*[clinic input]
+compile as builtin_compile
+
+ source: object
+ filename: object(converter="PyUnicode_FSDecoder")
+ mode: str
+ flags: int = 0
+ dont_inherit: bool(accept={int}) = False
+ optimize: int = -1
+ *
+ _feature_version as feature_version: int = -1
+
+Compile source into a code object that can be executed by exec() or eval().
+
+The source code may represent a Python module, statement or expression.
+The filename will be used for run-time error messages.
+The mode must be 'exec' to compile a module, 'single' to compile a
+single (interactive) statement, or 'eval' to compile an expression.
+The flags argument, if present, controls which future statements influence
+the compilation of the code.
+The dont_inherit argument, if true, stops the compilation inheriting
+the effects of any future statements in effect in the code calling
+compile; if absent or false these statements do influence the compilation,
+in addition to any features explicitly specified.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename,
+ const char *mode, int flags, int dont_inherit,
+ int optimize, int feature_version)
+/*[clinic end generated code: output=b0c09c84f116d3d7 input=40171fb92c1d580d]*/
+{
+ PyObject *source_copy;
+ const char *str;
+ int compile_mode = -1;
+ int is_ast;
+ int start[] = {Py_file_input, Py_eval_input, Py_single_input, Py_func_type_input};
+ PyObject *result;
+
+ PyCompilerFlags cf = _PyCompilerFlags_INIT;
+ cf.cf_flags = flags | PyCF_SOURCE_IS_UTF8;
+ if (feature_version >= 0 && (flags & PyCF_ONLY_AST)) {
+ cf.cf_feature_version = feature_version;
+ }
+
+ if (flags &
+ ~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_COMPILE_MASK))
+ {
+ PyErr_SetString(PyExc_ValueError,
+ "compile(): unrecognised flags");
+ goto error;
+ }
+ /* XXX Warn if (supplied_flags & PyCF_MASK_OBSOLETE) != 0? */
+
+ if (optimize < -1 || optimize > 2) {
+ PyErr_SetString(PyExc_ValueError,
+ "compile(): invalid optimize value");
+ goto error;
+ }
+
+ if (!dont_inherit) {
+ PyEval_MergeCompilerFlags(&cf);
+ }
+
+ if (strcmp(mode, "exec") == 0)
+ compile_mode = 0;
+ else if (strcmp(mode, "eval") == 0)
+ compile_mode = 1;
+ else if (strcmp(mode, "single") == 0)
+ compile_mode = 2;
+ else if (strcmp(mode, "func_type") == 0) {
+ if (!(flags & PyCF_ONLY_AST)) {
+ PyErr_SetString(PyExc_ValueError,
+ "compile() mode 'func_type' requires flag PyCF_ONLY_AST");
+ goto error;
+ }
+ compile_mode = 3;
+ }
+ else {
+ const char *msg;
+ if (flags & PyCF_ONLY_AST)
+ msg = "compile() mode must be 'exec', 'eval', 'single' or 'func_type'";
+ else
+ msg = "compile() mode must be 'exec', 'eval' or 'single'";
+ PyErr_SetString(PyExc_ValueError, msg);
+ goto error;
+ }
+
+ is_ast = PyAST_Check(source);
+ if (is_ast == -1)
+ goto error;
+ if (is_ast) {
+ if (flags & PyCF_ONLY_AST) {
+ Py_INCREF(source);
+ result = source;
+ }
+ else {
+ PyArena *arena;
+ mod_ty mod;
+
+ arena = PyArena_New();
+ if (arena == NULL)
+ goto error;
+ mod = PyAST_obj2mod(source, arena, compile_mode);
+ if (mod == NULL) {
+ PyArena_Free(arena);
+ goto error;
+ }
+ if (!PyAST_Validate(mod)) {
+ PyArena_Free(arena);
+ goto error;
+ }
+ result = (PyObject*)PyAST_CompileObject(mod, filename,
+ &cf, optimize, arena);
+ PyArena_Free(arena);
+ }
+ goto finally;
+ }
+
+ str = _Py_SourceAsString(source, "compile", "string, bytes or AST", &cf, &source_copy);
+ if (str == NULL)
+ goto error;
+
+ result = Py_CompileStringObject(str, filename, start[compile_mode], &cf, optimize);
+
+ Py_XDECREF(source_copy);
+ goto finally;
+
+error:
+ result = NULL;
+finally:
+ Py_DECREF(filename);
+ return result;
+}
+
+/* AC: cannot convert yet, as needs PEP 457 group support in inspect */
+static PyObject *
+builtin_dir(PyObject *self, PyObject *args)
+{
+ PyObject *arg = NULL;
+
+ if (!PyArg_UnpackTuple(args, "dir", 0, 1, &arg))
+ return NULL;
+ return PyObject_Dir(arg);
+}
+
+PyDoc_STRVAR(dir_doc,
+"dir([object]) -> list of strings\n"
+"\n"
+"If called without an argument, return the names in the current scope.\n"
+"Else, return an alphabetized list of names comprising (some of) the attributes\n"
+"of the given object, and of attributes reachable from it.\n"
+"If the object supplies a method named __dir__, it will be used; otherwise\n"
+"the default dir() logic is used and returns:\n"
+" for a module object: the module's attributes.\n"
+" for a class object: its attributes, and recursively the attributes\n"
+" of its bases.\n"
+" for any other object: its attributes, its class's attributes, and\n"
+" recursively the attributes of its class's base classes.");
+
+/*[clinic input]
+divmod as builtin_divmod
+
+ x: object
+ y: object
+ /
+
+Return the tuple (x//y, x%y). Invariant: div*y + mod == x.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_divmod_impl(PyObject *module, PyObject *x, PyObject *y)
+/*[clinic end generated code: output=b06d8a5f6e0c745e input=175ad9c84ff41a85]*/
+{
+ return PyNumber_Divmod(x, y);
+}
+
+
+/*[clinic input]
+eval as builtin_eval
+
+ source: object
+ globals: object = None
+ locals: object = None
+ /
+
+Evaluate the given source in the context of globals and locals.
+
+The source may be a string representing a Python expression
+or a code object as returned by compile().
+The globals must be a dictionary and locals can be any mapping,
+defaulting to the current globals and locals.
+If only globals is given, locals defaults to it.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals,
+ PyObject *locals)
+/*[clinic end generated code: output=0a0824aa70093116 input=11ee718a8640e527]*/
+{
+ PyObject *result, *source_copy;
+ const char *str;
+
+ if (locals != Py_None && !PyMapping_Check(locals)) {
+ PyErr_SetString(PyExc_TypeError, "locals must be a mapping");
+ return NULL;
+ }
+ if (globals != Py_None && !PyDict_Check(globals)) {
+ PyErr_SetString(PyExc_TypeError, PyMapping_Check(globals) ?
+ "globals must be a real dict; try eval(expr, {}, mapping)"
+ : "globals must be a dict");
+ return NULL;
+ }
+ if (globals == Py_None) {
+ globals = PyEval_GetGlobals();
+ if (locals == Py_None) {
+ locals = PyEval_GetLocals();
+ if (locals == NULL)
+ return NULL;
+ }
+ }
+ else if (locals == Py_None)
+ locals = globals;
+
+ if (globals == NULL || locals == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "eval must be given globals and locals "
+ "when called without a frame");
+ return NULL;
+ }
+
+ if (_PyDict_GetItemIdWithError(globals, &PyId___builtins__) == NULL) {
+ if (_PyDict_SetItemId(globals, &PyId___builtins__,
+ PyEval_GetBuiltins()) != 0)
+ return NULL;
+ }
+ else if (PyErr_Occurred()) {
+ return NULL;
+ }
+
+ if (PyCode_Check(source)) {
+ if (PySys_Audit("exec", "O", source) < 0) {
+ return NULL;
+ }
+
+ if (PyCode_GetNumFree((PyCodeObject *)source) > 0) {
+ PyErr_SetString(PyExc_TypeError,
+ "code object passed to eval() may not contain free variables");
+ return NULL;
+ }
+ return PyEval_EvalCode(source, globals, locals);
+ }
+
+ PyCompilerFlags cf = _PyCompilerFlags_INIT;
+ cf.cf_flags = PyCF_SOURCE_IS_UTF8;
+ str = _Py_SourceAsString(source, "eval", "string, bytes or code", &cf, &source_copy);
+ if (str == NULL)
+ return NULL;
+
+ while (*str == ' ' || *str == '\t')
+ str++;
+
+ (void)PyEval_MergeCompilerFlags(&cf);
+ result = PyRun_StringFlags(str, Py_eval_input, globals, locals, &cf);
+ Py_XDECREF(source_copy);
+ return result;
+}
+
+/*[clinic input]
+exec as builtin_exec
+
+ source: object
+ globals: object = None
+ locals: object = None
+ /
+
+Execute the given source in the context of globals and locals.
+
+The source may be a string representing one or more Python statements
+or a code object as returned by compile().
+The globals must be a dictionary and locals can be any mapping,
+defaulting to the current globals and locals.
+If only globals is given, locals defaults to it.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals,
+ PyObject *locals)
+/*[clinic end generated code: output=3c90efc6ab68ef5d input=01ca3e1c01692829]*/
+{
+ PyObject *v;
+
+ if (globals == Py_None) {
+ globals = PyEval_GetGlobals();
+ if (locals == Py_None) {
+ locals = PyEval_GetLocals();
+ if (locals == NULL)
+ return NULL;
+ }
+ if (!globals || !locals) {
+ PyErr_SetString(PyExc_SystemError,
+ "globals and locals cannot be NULL");
+ return NULL;
+ }
+ }
+ else if (locals == Py_None)
+ locals = globals;
+
+ if (!PyDict_Check(globals)) {
+ PyErr_Format(PyExc_TypeError, "exec() globals must be a dict, not %.100s",
+ Py_TYPE(globals)->tp_name);
+ return NULL;
+ }
+ if (!PyMapping_Check(locals)) {
+ PyErr_Format(PyExc_TypeError,
+ "locals must be a mapping or None, not %.100s",
+ Py_TYPE(locals)->tp_name);
+ return NULL;
+ }
+ if (_PyDict_GetItemIdWithError(globals, &PyId___builtins__) == NULL) {
+ if (_PyDict_SetItemId(globals, &PyId___builtins__,
+ PyEval_GetBuiltins()) != 0)
+ return NULL;
+ }
+ else if (PyErr_Occurred()) {
+ return NULL;
+ }
+
+ if (PyCode_Check(source)) {
+ if (PySys_Audit("exec", "O", source) < 0) {
+ return NULL;
+ }
+
+ if (PyCode_GetNumFree((PyCodeObject *)source) > 0) {
+ PyErr_SetString(PyExc_TypeError,
+ "code object passed to exec() may not "
+ "contain free variables");
+ return NULL;
+ }
+ v = PyEval_EvalCode(source, globals, locals);
+ }
+ else {
+ PyObject *source_copy;
+ const char *str;
+ PyCompilerFlags cf = _PyCompilerFlags_INIT;
+ cf.cf_flags = PyCF_SOURCE_IS_UTF8;
+ str = _Py_SourceAsString(source, "exec",
+ "string, bytes or code", &cf,
+ &source_copy);
+ if (str == NULL)
+ return NULL;
+ if (PyEval_MergeCompilerFlags(&cf))
+ v = PyRun_StringFlags(str, Py_file_input, globals,
+ locals, &cf);
+ else
+ v = PyRun_String(str, Py_file_input, globals, locals);
+ Py_XDECREF(source_copy);
+ }
+ if (v == NULL)
+ return NULL;
+ Py_DECREF(v);
+ Py_RETURN_NONE;
+}
+
+
+/* AC: cannot convert yet, as needs PEP 457 group support in inspect */
+static PyObject *
+builtin_getattr(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *v, *name, *result;
+
+ if (!_PyArg_CheckPositional("getattr", nargs, 2, 3))
+ return NULL;
+
+ v = args[0];
+ name = args[1];
+ if (!PyUnicode_Check(name)) {
+ PyErr_SetString(PyExc_TypeError,
+ "getattr(): attribute name must be string");
+ return NULL;
+ }
+ if (nargs > 2) {
+ if (_PyObject_LookupAttr(v, name, &result) == 0) {
+ PyObject *dflt = args[2];
+ Py_INCREF(dflt);
+ return dflt;
+ }
+ }
+ else {
+ result = PyObject_GetAttr(v, name);
+ }
+ return result;
+}
+
+PyDoc_STRVAR(getattr_doc,
+"getattr(object, name[, default]) -> value\n\
+\n\
+Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.\n\
+When a default argument is given, it is returned when the attribute doesn't\n\
+exist; without it, an exception is raised in that case.");
+
+
+/*[clinic input]
+globals as builtin_globals
+
+Return the dictionary containing the current scope's global variables.
+
+NOTE: Updates to this dictionary *will* affect name lookups in the current
+global scope and vice-versa.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_globals_impl(PyObject *module)
+/*[clinic end generated code: output=e5dd1527067b94d2 input=9327576f92bb48ba]*/
+{
+ PyObject *d;
+
+ d = PyEval_GetGlobals();
+ Py_XINCREF(d);
+ return d;
+}
+
+
+/*[clinic input]
+hasattr as builtin_hasattr
+
+ obj: object
+ name: object
+ /
+
+Return whether the object has an attribute with the given name.
+
+This is done by calling getattr(obj, name) and catching AttributeError.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_hasattr_impl(PyObject *module, PyObject *obj, PyObject *name)
+/*[clinic end generated code: output=a7aff2090a4151e5 input=0faec9787d979542]*/
+{
+ PyObject *v;
+
+ if (!PyUnicode_Check(name)) {
+ PyErr_SetString(PyExc_TypeError,
+ "hasattr(): attribute name must be string");
+ return NULL;
+ }
+ if (_PyObject_LookupAttr(obj, name, &v) < 0) {
+ return NULL;
+ }
+ if (v == NULL) {
+ Py_RETURN_FALSE;
+ }
+ Py_DECREF(v);
+ Py_RETURN_TRUE;
+}
+
+
+/* AC: gdb's integration with CPython relies on builtin_id having
+ * the *exact* parameter names of "self" and "v", so we ensure we
+ * preserve those name rather than using the AC defaults.
+ */
+/*[clinic input]
+id as builtin_id
+
+ self: self(type="PyModuleDef *")
+ obj as v: object
+ /
+
+Return the identity of an object.
+
+This is guaranteed to be unique among simultaneously existing objects.
+(CPython uses the object's memory address.)
+[clinic start generated code]*/
+
+static PyObject *
+builtin_id(PyModuleDef *self, PyObject *v)
+/*[clinic end generated code: output=0aa640785f697f65 input=5a534136419631f4]*/
+{
+ PyObject *id = PyLong_FromVoidPtr(v);
+
+ if (id && PySys_Audit("builtins.id", "O", id) < 0) {
+ Py_DECREF(id);
+ return NULL;
+ }
+
+ return id;
+}
+
+
+/* map object ************************************************************/
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *iters;
+ PyObject *func;
+} mapobject;
+
+static PyObject *
+map_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *it, *iters, *func;
+ mapobject *lz;
+ Py_ssize_t numargs, i;
+
+ if (type == &PyMap_Type && !_PyArg_NoKeywords("map", kwds))
+ return NULL;
+
+ numargs = PyTuple_Size(args);
+ if (numargs < 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "map() must have at least two arguments.");
+ return NULL;
+ }
+
+ iters = PyTuple_New(numargs-1);
+ if (iters == NULL)
+ return NULL;
+
+ for (i=1 ; i<numargs ; i++) {
+ /* Get iterator. */
+ it = PyObject_GetIter(PyTuple_GET_ITEM(args, i));
+ if (it == NULL) {
+ Py_DECREF(iters);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(iters, i-1, it);
+ }
+
+ /* create mapobject structure */
+ lz = (mapobject *)type->tp_alloc(type, 0);
+ if (lz == NULL) {
+ Py_DECREF(iters);
+ return NULL;
+ }
+ lz->iters = iters;
+ func = PyTuple_GET_ITEM(args, 0);
+ Py_INCREF(func);
+ lz->func = func;
+
+ return (PyObject *)lz;
+}
+
+static void
+map_dealloc(mapobject *lz)
+{
+ PyObject_GC_UnTrack(lz);
+ Py_XDECREF(lz->iters);
+ Py_XDECREF(lz->func);
+ Py_TYPE(lz)->tp_free(lz);
+}
+
+static int
+map_traverse(mapobject *lz, visitproc visit, void *arg)
+{
+ Py_VISIT(lz->iters);
+ Py_VISIT(lz->func);
+ return 0;
+}
+
+static PyObject *
+map_next(mapobject *lz)
+{
+ PyObject *small_stack[_PY_FASTCALL_SMALL_STACK];
+ PyObject **stack;
+ PyObject *result = NULL;
+ PyThreadState *tstate = _PyThreadState_GET();
+
+ const Py_ssize_t niters = PyTuple_GET_SIZE(lz->iters);
+ if (niters <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) {
+ stack = small_stack;
+ }
+ else {
+ stack = PyMem_Malloc(niters * sizeof(stack[0]));
+ if (stack == NULL) {
+ _PyErr_NoMemory(tstate);
+ return NULL;
+ }
+ }
+
+ Py_ssize_t nargs = 0;
+ for (Py_ssize_t i=0; i < niters; i++) {
+ PyObject *it = PyTuple_GET_ITEM(lz->iters, i);
+ PyObject *val = Py_TYPE(it)->tp_iternext(it);
+ if (val == NULL) {
+ goto exit;
+ }
+ stack[i] = val;
+ nargs++;
+ }
+
+ result = _PyObject_VectorcallTstate(tstate, lz->func, stack, nargs, NULL);
+
+exit:
+ for (Py_ssize_t i=0; i < nargs; i++) {
+ Py_DECREF(stack[i]);
+ }
+ if (stack != small_stack) {
+ PyMem_Free(stack);
+ }
+ return result;
+}
+
+static PyObject *
+map_reduce(mapobject *lz, PyObject *Py_UNUSED(ignored))
+{
+ Py_ssize_t numargs = PyTuple_GET_SIZE(lz->iters);
+ PyObject *args = PyTuple_New(numargs+1);
+ Py_ssize_t i;
+ if (args == NULL)
+ return NULL;
+ Py_INCREF(lz->func);
+ PyTuple_SET_ITEM(args, 0, lz->func);
+ for (i = 0; i<numargs; i++){
+ PyObject *it = PyTuple_GET_ITEM(lz->iters, i);
+ Py_INCREF(it);
+ PyTuple_SET_ITEM(args, i+1, it);
+ }
+
+ return Py_BuildValue("ON", Py_TYPE(lz), args);
+}
+
+static PyMethodDef map_methods[] = {
+ {"__reduce__", (PyCFunction)map_reduce, METH_NOARGS, reduce_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+
+PyDoc_STRVAR(map_doc,
+"map(func, *iterables) --> map object\n\
+\n\
+Make an iterator that computes the function using arguments from\n\
+each of the iterables. Stops when the shortest iterable is exhausted.");
+
+PyTypeObject PyMap_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "map", /* tp_name */
+ sizeof(mapobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)map_dealloc, /* tp_dealloc */
+ 0, /* tp_vectorcall_offset */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_as_async */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ map_doc, /* tp_doc */
+ (traverseproc)map_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)map_next, /* tp_iternext */
+ map_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ map_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+
+/* AC: cannot convert yet, as needs PEP 457 group support in inspect */
+static PyObject *
+builtin_next(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *it, *res;
+
+ if (!_PyArg_CheckPositional("next", nargs, 1, 2))
+ return NULL;
+
+ it = args[0];
+ if (!PyIter_Check(it)) {
+ PyErr_Format(PyExc_TypeError,
+ "'%.200s' object is not an iterator",
+ Py_TYPE(it)->tp_name);
+ return NULL;
+ }
+
+ res = (*Py_TYPE(it)->tp_iternext)(it);
+ if (res != NULL) {
+ return res;
+ } else if (nargs > 1) {
+ PyObject *def = args[1];
+ if (PyErr_Occurred()) {
+ if(!PyErr_ExceptionMatches(PyExc_StopIteration))
+ return NULL;
+ PyErr_Clear();
+ }
+ Py_INCREF(def);
+ return def;
+ } else if (PyErr_Occurred()) {
+ return NULL;
+ } else {
+ PyErr_SetNone(PyExc_StopIteration);
+ return NULL;
+ }
+}
+
+PyDoc_STRVAR(next_doc,
+"next(iterator[, default])\n\
+\n\
+Return the next item from the iterator. If default is given and the iterator\n\
+is exhausted, it is returned instead of raising StopIteration.");
+
+
+/*[clinic input]
+setattr as builtin_setattr
+
+ obj: object
+ name: object
+ value: object
+ /
+
+Sets the named attribute on the given object to the specified value.
+
+setattr(x, 'y', v) is equivalent to ``x.y = v''
+[clinic start generated code]*/
+
+static PyObject *
+builtin_setattr_impl(PyObject *module, PyObject *obj, PyObject *name,
+ PyObject *value)
+/*[clinic end generated code: output=dc2ce1d1add9acb4 input=bd2b7ca6875a1899]*/
+{
+ if (PyObject_SetAttr(obj, name, value) != 0)
+ return NULL;
+ Py_RETURN_NONE;
+}
+
+
+/*[clinic input]
+delattr as builtin_delattr
+
+ obj: object
+ name: object
+ /
+
+Deletes the named attribute from the given object.
+
+delattr(x, 'y') is equivalent to ``del x.y''
+[clinic start generated code]*/
+
+static PyObject *
+builtin_delattr_impl(PyObject *module, PyObject *obj, PyObject *name)
+/*[clinic end generated code: output=85134bc58dff79fa input=db16685d6b4b9410]*/
+{
+ if (PyObject_SetAttr(obj, name, (PyObject *)NULL) != 0)
+ return NULL;
+ Py_RETURN_NONE;
+}
+
+
+/*[clinic input]
+hash as builtin_hash
+
+ obj: object
+ /
+
+Return the hash value for the given object.
+
+Two objects that compare equal must also have the same hash value, but the
+reverse is not necessarily true.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_hash(PyObject *module, PyObject *obj)
+/*[clinic end generated code: output=237668e9d7688db7 input=58c48be822bf9c54]*/
+{
+ Py_hash_t x;
+
+ x = PyObject_Hash(obj);
+ if (x == -1)
+ return NULL;
+ return PyLong_FromSsize_t(x);
+}
+
+
+/*[clinic input]
+hex as builtin_hex
+
+ number: object
+ /
+
+Return the hexadecimal representation of an integer.
+
+ >>> hex(12648430)
+ '0xc0ffee'
+[clinic start generated code]*/
+
+static PyObject *
+builtin_hex(PyObject *module, PyObject *number)
+/*[clinic end generated code: output=e46b612169099408 input=e645aff5fc7d540e]*/
+{
+ return PyNumber_ToBase(number, 16);
+}
+
+
+/* AC: cannot convert yet, as needs PEP 457 group support in inspect */
+static PyObject *
+builtin_iter(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *v;
+
+ if (!_PyArg_CheckPositional("iter", nargs, 1, 2))
+ return NULL;
+ v = args[0];
+ if (nargs == 1)
+ return PyObject_GetIter(v);
+ if (!PyCallable_Check(v)) {
+ PyErr_SetString(PyExc_TypeError,
+ "iter(v, w): v must be callable");
+ return NULL;
+ }
+ PyObject *sentinel = args[1];
+ return PyCallIter_New(v, sentinel);
+}
+
+PyDoc_STRVAR(iter_doc,
+"iter(iterable) -> iterator\n\
+iter(callable, sentinel) -> iterator\n\
+\n\
+Get an iterator from an object. In the first form, the argument must\n\
+supply its own iterator, or be a sequence.\n\
+In the second form, the callable is called until it returns the sentinel.");
+
+
+/*[clinic input]
+len as builtin_len
+
+ obj: object
+ /
+
+Return the number of items in a container.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_len(PyObject *module, PyObject *obj)
+/*[clinic end generated code: output=fa7a270d314dfb6c input=bc55598da9e9c9b5]*/
+{
+ Py_ssize_t res;
+
+ res = PyObject_Size(obj);
+ if (res < 0) {
+ assert(PyErr_Occurred());
+ return NULL;
+ }
+ return PyLong_FromSsize_t(res);
+}
+
+
+/*[clinic input]
+locals as builtin_locals
+
+Return a dictionary containing the current scope's local variables.
+
+NOTE: Whether or not updates to this dictionary will affect name lookups in
+the local scope and vice-versa is *implementation dependent* and not
+covered by any backwards compatibility guarantees.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_locals_impl(PyObject *module)
+/*[clinic end generated code: output=b46c94015ce11448 input=7874018d478d5c4b]*/
+{
+ PyObject *d;
+
+ d = PyEval_GetLocals();
+ Py_XINCREF(d);
+ return d;
+}
+
+
+static PyObject *
+min_max(PyObject *args, PyObject *kwds, int op)
+{
+ PyObject *v, *it, *item, *val, *maxitem, *maxval, *keyfunc=NULL;
+ PyObject *emptytuple, *defaultval = NULL;
+ static char *kwlist[] = {"key", "default", NULL};
+ const char *name = op == Py_LT ? "min" : "max";
+ const int positional = PyTuple_Size(args) > 1;
+ int ret;
+
+ if (positional) {
+ v = args;
+ }
+ else if (!PyArg_UnpackTuple(args, name, 1, 1, &v)) {
+ if (PyExceptionClass_Check(PyExc_TypeError)) {
+ PyErr_Format(PyExc_TypeError, "%s expected at least 1 argument, got 0", name);
+ }
+ return NULL;
+ }
+
+ emptytuple = PyTuple_New(0);
+ if (emptytuple == NULL)
+ return NULL;
+ ret = PyArg_ParseTupleAndKeywords(emptytuple, kwds,
+ (op == Py_LT) ? "|$OO:min" : "|$OO:max",
+ kwlist, &keyfunc, &defaultval);
+ Py_DECREF(emptytuple);
+ if (!ret)
+ return NULL;
+
+ if (positional && defaultval != NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "Cannot specify a default for %s() with multiple "
+ "positional arguments", name);
+ return NULL;
+ }
+
+ it = PyObject_GetIter(v);
+ if (it == NULL) {
+ return NULL;
+ }
+
+ if (keyfunc == Py_None) {
+ keyfunc = NULL;
+ }
+
+ maxitem = NULL; /* the result */
+ maxval = NULL; /* the value associated with the result */
+ while (( item = PyIter_Next(it) )) {
+ /* get the value from the key function */
+ if (keyfunc != NULL) {
+ val = PyObject_CallOneArg(keyfunc, item);
+ if (val == NULL)
+ goto Fail_it_item;
+ }
+ /* no key function; the value is the item */
+ else {
+ val = item;
+ Py_INCREF(val);
+ }
+
+ /* maximum value and item are unset; set them */
+ if (maxval == NULL) {
+ maxitem = item;
+ maxval = val;
+ }
+ /* maximum value and item are set; update them as necessary */
+ else {
+ int cmp = PyObject_RichCompareBool(val, maxval, op);
+ if (cmp < 0)
+ goto Fail_it_item_and_val;
+ else if (cmp > 0) {
+ Py_DECREF(maxval);
+ Py_DECREF(maxitem);
+ maxval = val;
+ maxitem = item;
+ }
+ else {
+ Py_DECREF(item);
+ Py_DECREF(val);
+ }
+ }
+ }
+ if (PyErr_Occurred())
+ goto Fail_it;
+ if (maxval == NULL) {
+ assert(maxitem == NULL);
+ if (defaultval != NULL) {
+ Py_INCREF(defaultval);
+ maxitem = defaultval;
+ } else {
+ PyErr_Format(PyExc_ValueError,
+ "%s() arg is an empty sequence", name);
+ }
+ }
+ else
+ Py_DECREF(maxval);
+ Py_DECREF(it);
+ return maxitem;
+
+Fail_it_item_and_val:
+ Py_DECREF(val);
+Fail_it_item:
+ Py_DECREF(item);
+Fail_it:
+ Py_XDECREF(maxval);
+ Py_XDECREF(maxitem);
+ Py_DECREF(it);
+ return NULL;
+}
+
+/* AC: cannot convert yet, waiting for *args support */
+static PyObject *
+builtin_min(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ return min_max(args, kwds, Py_LT);
+}
+
+PyDoc_STRVAR(min_doc,
+"min(iterable, *[, default=obj, key=func]) -> value\n\
+min(arg1, arg2, *args, *[, key=func]) -> value\n\
+\n\
+With a single iterable argument, return its smallest item. The\n\
+default keyword-only argument specifies an object to return if\n\
+the provided iterable is empty.\n\
+With two or more arguments, return the smallest argument.");
+
+
+/* AC: cannot convert yet, waiting for *args support */
+static PyObject *
+builtin_max(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ return min_max(args, kwds, Py_GT);
+}
+
+PyDoc_STRVAR(max_doc,
+"max(iterable, *[, default=obj, key=func]) -> value\n\
+max(arg1, arg2, *args, *[, key=func]) -> value\n\
+\n\
+With a single iterable argument, return its biggest item. The\n\
+default keyword-only argument specifies an object to return if\n\
+the provided iterable is empty.\n\
+With two or more arguments, return the largest argument.");
+
+
+/*[clinic input]
+oct as builtin_oct
+
+ number: object
+ /
+
+Return the octal representation of an integer.
+
+ >>> oct(342391)
+ '0o1234567'
+[clinic start generated code]*/
+
+static PyObject *
+builtin_oct(PyObject *module, PyObject *number)
+/*[clinic end generated code: output=40a34656b6875352 input=ad6b274af4016c72]*/
+{
+ return PyNumber_ToBase(number, 8);
+}
+
+
+/*[clinic input]
+ord as builtin_ord
+
+ c: object
+ /
+
+Return the Unicode code point for a one-character string.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_ord(PyObject *module, PyObject *c)
+/*[clinic end generated code: output=4fa5e87a323bae71 input=3064e5d6203ad012]*/
+{
+ long ord;
+ Py_ssize_t size;
+
+ if (PyBytes_Check(c)) {
+ size = PyBytes_GET_SIZE(c);
+ if (size == 1) {
+ ord = (long)((unsigned char)*PyBytes_AS_STRING(c));
+ return PyLong_FromLong(ord);
+ }
+ }
+ else if (PyUnicode_Check(c)) {
+ if (PyUnicode_READY(c) == -1)
+ return NULL;
+ size = PyUnicode_GET_LENGTH(c);
+ if (size == 1) {
+ ord = (long)PyUnicode_READ_CHAR(c, 0);
+ return PyLong_FromLong(ord);
+ }
+ }
+ else if (PyByteArray_Check(c)) {
+ /* XXX Hopefully this is temporary */
+ size = PyByteArray_GET_SIZE(c);
+ if (size == 1) {
+ ord = (long)((unsigned char)*PyByteArray_AS_STRING(c));
+ return PyLong_FromLong(ord);
+ }
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "ord() expected string of length 1, but " \
+ "%.200s found", Py_TYPE(c)->tp_name);
+ return NULL;
+ }
+
+ PyErr_Format(PyExc_TypeError,
+ "ord() expected a character, "
+ "but string of length %zd found",
+ size);
+ return NULL;
+}
+
+
+/*[clinic input]
+pow as builtin_pow
+
+ base: object
+ exp: object
+ mod: object = None
+
+Equivalent to base**exp with 2 arguments or base**exp % mod with 3 arguments
+
+Some types, such as ints, are able to use a more efficient algorithm when
+invoked using the three argument form.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_pow_impl(PyObject *module, PyObject *base, PyObject *exp,
+ PyObject *mod)
+/*[clinic end generated code: output=3ca1538221bbf15f input=435dbd48a12efb23]*/
+{
+ return PyNumber_Power(base, exp, mod);
+}
+
+
+/* AC: cannot convert yet, waiting for *args support */
+static PyObject *
+builtin_print(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ static const char * const _keywords[] = {"sep", "end", "file", "flush", 0};
+ static struct _PyArg_Parser _parser = {"|OOOp:print", _keywords, 0};
+ PyObject *sep = NULL, *end = NULL, *file = NULL;
+ int flush = 0;
+ int i, err;
+
+ if (kwnames != NULL &&
+ !_PyArg_ParseStackAndKeywords(args + nargs, 0, kwnames, &_parser,
+ &sep, &end, &file, &flush)) {
+ return NULL;
+ }
+
+ if (file == NULL || file == Py_None) {
+ file = _PySys_GetObjectId(&PyId_stdout);
+ if (file == NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
+ return NULL;
+ }
+
+ /* sys.stdout may be None when FILE* stdout isn't connected */
+ if (file == Py_None)
+ Py_RETURN_NONE;
+ }
+
+ if (sep == Py_None) {
+ sep = NULL;
+ }
+ else if (sep && !PyUnicode_Check(sep)) {
+ PyErr_Format(PyExc_TypeError,
+ "sep must be None or a string, not %.200s",
+ Py_TYPE(sep)->tp_name);
+ return NULL;
+ }
+ if (end == Py_None) {
+ end = NULL;
+ }
+ else if (end && !PyUnicode_Check(end)) {
+ PyErr_Format(PyExc_TypeError,
+ "end must be None or a string, not %.200s",
+ Py_TYPE(end)->tp_name);
+ return NULL;
+ }
+
+ for (i = 0; i < nargs; i++) {
+ if (i > 0) {
+ if (sep == NULL)
+ err = PyFile_WriteString(" ", file);
+ else
+ err = PyFile_WriteObject(sep, file,
+ Py_PRINT_RAW);
+ if (err)
+ return NULL;
+ }
+ err = PyFile_WriteObject(args[i], file, Py_PRINT_RAW);
+ if (err)
+ return NULL;
+ }
+
+ if (end == NULL)
+ err = PyFile_WriteString("\n", file);
+ else
+ err = PyFile_WriteObject(end, file, Py_PRINT_RAW);
+ if (err)
+ return NULL;
+
+ if (flush) {
+ PyObject *tmp = _PyObject_CallMethodIdNoArgs(file, &PyId_flush);
+ if (tmp == NULL)
+ return NULL;
+ Py_DECREF(tmp);
+ }
+
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(print_doc,
+"print(value, ..., sep=' ', end='\\n', file=sys.stdout, flush=False)\n\
+\n\
+Prints the values to a stream, or to sys.stdout by default.\n\
+Optional keyword arguments:\n\
+file: a file-like object (stream); defaults to the current sys.stdout.\n\
+sep: string inserted between values, default a space.\n\
+end: string appended after the last value, default a newline.\n\
+flush: whether to forcibly flush the stream.");
+
+
+/*[clinic input]
+input as builtin_input
+
+ prompt: object(c_default="NULL") = None
+ /
+
+Read a string from standard input. The trailing newline is stripped.
+
+The prompt string, if given, is printed to standard output without a
+trailing newline before reading input.
+
+If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError.
+On *nix systems, readline is used if available.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_input_impl(PyObject *module, PyObject *prompt)
+/*[clinic end generated code: output=83db5a191e7a0d60 input=5e8bb70c2908fe3c]*/
+{
+ PyObject *fin = _PySys_GetObjectId(&PyId_stdin);
+ PyObject *fout = _PySys_GetObjectId(&PyId_stdout);
+ PyObject *ferr = _PySys_GetObjectId(&PyId_stderr);
+ PyObject *tmp;
+ long fd;
+ int tty;
+
+ /* Check that stdin/out/err are intact */
+ if (fin == NULL || fin == Py_None) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "input(): lost sys.stdin");
+ return NULL;
+ }
+ if (fout == NULL || fout == Py_None) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "input(): lost sys.stdout");
+ return NULL;
+ }
+ if (ferr == NULL || ferr == Py_None) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "input(): lost sys.stderr");
+ return NULL;
+ }
+
+ if (PySys_Audit("builtins.input", "O", prompt ? prompt : Py_None) < 0) {
+ return NULL;
+ }
+
+ /* First of all, flush stderr */
+ tmp = _PyObject_CallMethodIdNoArgs(ferr, &PyId_flush);
+ if (tmp == NULL)
+ PyErr_Clear();
+ else
+ Py_DECREF(tmp);
+
+ /* We should only use (GNU) readline if Python's sys.stdin and
+ sys.stdout are the same as C's stdin and stdout, because we
+ need to pass it those. */
+ tmp = _PyObject_CallMethodIdNoArgs(fin, &PyId_fileno);
+ if (tmp == NULL) {
+ PyErr_Clear();
+ tty = 0;
+ }
+ else {
+ fd = PyLong_AsLong(tmp);
+ Py_DECREF(tmp);
+ if (fd < 0 && PyErr_Occurred())
+ return NULL;
+ tty = fd == fileno(stdin) && isatty(fd);
+ }
+ if (tty) {
+ tmp = _PyObject_CallMethodIdNoArgs(fout, &PyId_fileno);
+ if (tmp == NULL) {
+ PyErr_Clear();
+ tty = 0;
+ }
+ else {
+ fd = PyLong_AsLong(tmp);
+ Py_DECREF(tmp);
+ if (fd < 0 && PyErr_Occurred())
+ return NULL;
+ tty = fd == fileno(stdout) && isatty(fd);
+ }
+ }
+
+ /* If we're interactive, use (GNU) readline */
+ if (tty) {
+ PyObject *po = NULL;
+ const char *promptstr;
+ char *s = NULL;
+ PyObject *stdin_encoding = NULL, *stdin_errors = NULL;
+ PyObject *stdout_encoding = NULL, *stdout_errors = NULL;
+ const char *stdin_encoding_str, *stdin_errors_str;
+ PyObject *result;
+ size_t len;
+
+ /* stdin is a text stream, so it must have an encoding. */
+ stdin_encoding = _PyObject_GetAttrId(fin, &PyId_encoding);
+ stdin_errors = _PyObject_GetAttrId(fin, &PyId_errors);
+ if (!stdin_encoding || !stdin_errors ||
+ !PyUnicode_Check(stdin_encoding) ||
+ !PyUnicode_Check(stdin_errors)) {
+ tty = 0;
+ goto _readline_errors;
+ }
+ stdin_encoding_str = PyUnicode_AsUTF8(stdin_encoding);
+ stdin_errors_str = PyUnicode_AsUTF8(stdin_errors);
+ if (!stdin_encoding_str || !stdin_errors_str)
+ goto _readline_errors;
+ tmp = _PyObject_CallMethodIdNoArgs(fout, &PyId_flush);
+ if (tmp == NULL)
+ PyErr_Clear();
+ else
+ Py_DECREF(tmp);
+ if (prompt != NULL) {
+ /* We have a prompt, encode it as stdout would */
+ const char *stdout_encoding_str, *stdout_errors_str;
+ PyObject *stringpo;
+ stdout_encoding = _PyObject_GetAttrId(fout, &PyId_encoding);
+ stdout_errors = _PyObject_GetAttrId(fout, &PyId_errors);
+ if (!stdout_encoding || !stdout_errors ||
+ !PyUnicode_Check(stdout_encoding) ||
+ !PyUnicode_Check(stdout_errors)) {
+ tty = 0;
+ goto _readline_errors;
+ }
+ stdout_encoding_str = PyUnicode_AsUTF8(stdout_encoding);
+ stdout_errors_str = PyUnicode_AsUTF8(stdout_errors);
+ if (!stdout_encoding_str || !stdout_errors_str)
+ goto _readline_errors;
+ stringpo = PyObject_Str(prompt);
+ if (stringpo == NULL)
+ goto _readline_errors;
+ po = PyUnicode_AsEncodedString(stringpo,
+ stdout_encoding_str, stdout_errors_str);
+ Py_CLEAR(stdout_encoding);
+ Py_CLEAR(stdout_errors);
+ Py_CLEAR(stringpo);
+ if (po == NULL)
+ goto _readline_errors;
+ assert(PyBytes_Check(po));
+ promptstr = PyBytes_AS_STRING(po);
+ }
+ else {
+ po = NULL;
+ promptstr = "";
+ }
+ s = PyOS_Readline(stdin, stdout, promptstr);
+ if (s == NULL) {
+ PyErr_CheckSignals();
+ if (!PyErr_Occurred())
+ PyErr_SetNone(PyExc_KeyboardInterrupt);
+ goto _readline_errors;
+ }
+
+ len = strlen(s);
+ if (len == 0) {
+ PyErr_SetNone(PyExc_EOFError);
+ result = NULL;
+ }
+ else {
+ if (len > PY_SSIZE_T_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "input: input too long");
+ result = NULL;
+ }
+ else {
+ len--; /* strip trailing '\n' */
+ if (len != 0 && s[len-1] == '\r')
+ len--; /* strip trailing '\r' */
+ result = PyUnicode_Decode(s, len, stdin_encoding_str,
+ stdin_errors_str);
+ }
+ }
+ Py_DECREF(stdin_encoding);
+ Py_DECREF(stdin_errors);
+ Py_XDECREF(po);
+ PyMem_FREE(s);
+
+ if (result != NULL) {
+ if (PySys_Audit("builtins.input/result", "O", result) < 0) {
+ return NULL;
+ }
+ }
+
+ return result;
+
+ _readline_errors:
+ Py_XDECREF(stdin_encoding);
+ Py_XDECREF(stdout_encoding);
+ Py_XDECREF(stdin_errors);
+ Py_XDECREF(stdout_errors);
+ Py_XDECREF(po);
+ if (tty)
+ return NULL;
+
+ PyErr_Clear();
+ }
+
+ /* Fallback if we're not interactive */
+ if (prompt != NULL) {
+ if (PyFile_WriteObject(prompt, fout, Py_PRINT_RAW) != 0)
+ return NULL;
+ }
+ tmp = _PyObject_CallMethodIdNoArgs(fout, &PyId_flush);
+ if (tmp == NULL)
+ PyErr_Clear();
+ else
+ Py_DECREF(tmp);
+ return PyFile_GetLine(fin, -1);
+}
+
+
+/*[clinic input]
+repr as builtin_repr
+
+ obj: object
+ /
+
+Return the canonical string representation of the object.
+
+For many object types, including most builtins, eval(repr(obj)) == obj.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_repr(PyObject *module, PyObject *obj)
+/*[clinic end generated code: output=7ed3778c44fd0194 input=1c9e6d66d3e3be04]*/
+{
+ return PyObject_Repr(obj);
+}
+
+
+/*[clinic input]
+round as builtin_round
+
+ number: object
+ ndigits: object = None
+
+Round a number to a given precision in decimal digits.
+
+The return value is an integer if ndigits is omitted or None. Otherwise
+the return value has the same type as the number. ndigits may be negative.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_round_impl(PyObject *module, PyObject *number, PyObject *ndigits)
+/*[clinic end generated code: output=ff0d9dd176c02ede input=275678471d7aca15]*/
+{
+ PyObject *round, *result;
+
+ if (Py_TYPE(number)->tp_dict == NULL) {
+ if (PyType_Ready(Py_TYPE(number)) < 0)
+ return NULL;
+ }
+
+ round = _PyObject_LookupSpecial(number, &PyId___round__);
+ if (round == NULL) {
+ if (!PyErr_Occurred())
+ PyErr_Format(PyExc_TypeError,
+ "type %.100s doesn't define __round__ method",
+ Py_TYPE(number)->tp_name);
+ return NULL;
+ }
+
+ if (ndigits == Py_None)
+ result = _PyObject_CallNoArg(round);
+ else
+ result = PyObject_CallOneArg(round, ndigits);
+ Py_DECREF(round);
+ return result;
+}
+
+
+/*AC: we need to keep the kwds dict intact to easily call into the
+ * list.sort method, which isn't currently supported in AC. So we just use
+ * the initially generated signature with a custom implementation.
+ */
+/* [disabled clinic input]
+sorted as builtin_sorted
+
+ iterable as seq: object
+ key as keyfunc: object = None
+ reverse: object = False
+
+Return a new list containing all items from the iterable in ascending order.
+
+A custom key function can be supplied to customize the sort order, and the
+reverse flag can be set to request the result in descending order.
+[end disabled clinic input]*/
+
+PyDoc_STRVAR(builtin_sorted__doc__,
+"sorted($module, iterable, /, *, key=None, reverse=False)\n"
+"--\n"
+"\n"
+"Return a new list containing all items from the iterable in ascending order.\n"
+"\n"
+"A custom key function can be supplied to customize the sort order, and the\n"
+"reverse flag can be set to request the result in descending order.");
+
+#define BUILTIN_SORTED_METHODDEF \
+ {"sorted", (PyCFunction)(void(*)(void))builtin_sorted, METH_FASTCALL | METH_KEYWORDS, builtin_sorted__doc__},
+
+static PyObject *
+builtin_sorted(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *newlist, *v, *seq, *callable;
+
+ /* Keyword arguments are passed through list.sort() which will check
+ them. */
+ if (!_PyArg_UnpackStack(args, nargs, "sorted", 1, 1, &seq))
+ return NULL;
+
+ newlist = PySequence_List(seq);
+ if (newlist == NULL)
+ return NULL;
+
+ callable = _PyObject_GetAttrId(newlist, &PyId_sort);
+ if (callable == NULL) {
+ Py_DECREF(newlist);
+ return NULL;
+ }
+
+ assert(nargs >= 1);
+ v = PyObject_Vectorcall(callable, args + 1, nargs - 1, kwnames);
+ Py_DECREF(callable);
+ if (v == NULL) {
+ Py_DECREF(newlist);
+ return NULL;
+ }
+ Py_DECREF(v);
+ return newlist;
+}
+
+
+/* AC: cannot convert yet, as needs PEP 457 group support in inspect */
+static PyObject *
+builtin_vars(PyObject *self, PyObject *args)
+{
+ PyObject *v = NULL;
+ PyObject *d;
+
+ if (!PyArg_UnpackTuple(args, "vars", 0, 1, &v))
+ return NULL;
+ if (v == NULL) {
+ d = PyEval_GetLocals();
+ Py_XINCREF(d);
+ }
+ else {
+ if (_PyObject_LookupAttrId(v, &PyId___dict__, &d) == 0) {
+ PyErr_SetString(PyExc_TypeError,
+ "vars() argument must have __dict__ attribute");
+ }
+ }
+ return d;
+}
+
+PyDoc_STRVAR(vars_doc,
+"vars([object]) -> dictionary\n\
+\n\
+Without arguments, equivalent to locals().\n\
+With an argument, equivalent to object.__dict__.");
+
+
+/*[clinic input]
+sum as builtin_sum
+
+ iterable: object
+ /
+ start: object(c_default="NULL") = 0
+
+Return the sum of a 'start' value (default: 0) plus an iterable of numbers
+
+When the iterable is empty, return the start value.
+This function is intended specifically for use with numeric values and may
+reject non-numeric types.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start)
+/*[clinic end generated code: output=df758cec7d1d302f input=162b50765250d222]*/
+{
+ PyObject *result = start;
+ PyObject *temp, *item, *iter;
+
+ iter = PyObject_GetIter(iterable);
+ if (iter == NULL)
+ return NULL;
+
+ if (result == NULL) {
+ result = PyLong_FromLong(0);
+ if (result == NULL) {
+ Py_DECREF(iter);
+ return NULL;
+ }
+ } else {
+ /* reject string values for 'start' parameter */
+ if (PyUnicode_Check(result)) {
+ PyErr_SetString(PyExc_TypeError,
+ "sum() can't sum strings [use ''.join(seq) instead]");
+ Py_DECREF(iter);
+ return NULL;
+ }
+ if (PyBytes_Check(result)) {
+ PyErr_SetString(PyExc_TypeError,
+ "sum() can't sum bytes [use b''.join(seq) instead]");
+ Py_DECREF(iter);
+ return NULL;
+ }
+ if (PyByteArray_Check(result)) {
+ PyErr_SetString(PyExc_TypeError,
+ "sum() can't sum bytearray [use b''.join(seq) instead]");
+ Py_DECREF(iter);
+ return NULL;
+ }
+ Py_INCREF(result);
+ }
+
+#ifndef SLOW_SUM
+ /* Fast addition by keeping temporary sums in C instead of new Python objects.
+ Assumes all inputs are the same type. If the assumption fails, default
+ to the more general routine.
+ */
+ if (PyLong_CheckExact(result)) {
+ int overflow;
+ long i_result = PyLong_AsLongAndOverflow(result, &overflow);
+ /* If this already overflowed, don't even enter the loop. */
+ if (overflow == 0) {
+ Py_DECREF(result);
+ result = NULL;
+ }
+ while(result == NULL) {
+ item = PyIter_Next(iter);
+ if (item == NULL) {
+ Py_DECREF(iter);
+ if (PyErr_Occurred())
+ return NULL;
+ return PyLong_FromLong(i_result);
+ }
+ if (PyLong_CheckExact(item) || PyBool_Check(item)) {
+ long b = PyLong_AsLongAndOverflow(item, &overflow);
+ if (overflow == 0 &&
+ (i_result >= 0 ? (b <= LONG_MAX - i_result)
+ : (b >= LONG_MIN - i_result)))
+ {
+ i_result += b;
+ Py_DECREF(item);
+ continue;
+ }
+ }
+ /* Either overflowed or is not an int. Restore real objects and process normally */
+ result = PyLong_FromLong(i_result);
+ if (result == NULL) {
+ Py_DECREF(item);
+ Py_DECREF(iter);
+ return NULL;
+ }
+ temp = PyNumber_Add(result, item);
+ Py_DECREF(result);
+ Py_DECREF(item);
+ result = temp;
+ if (result == NULL) {
+ Py_DECREF(iter);
+ return NULL;
+ }
+ }
+ }
+
+ if (PyFloat_CheckExact(result)) {
+ double f_result = PyFloat_AS_DOUBLE(result);
+ Py_DECREF(result);
+ result = NULL;
+ while(result == NULL) {
+ item = PyIter_Next(iter);
+ if (item == NULL) {
+ Py_DECREF(iter);
+ if (PyErr_Occurred())
+ return NULL;
+ return PyFloat_FromDouble(f_result);
+ }
+ if (PyFloat_CheckExact(item)) {
+ f_result += PyFloat_AS_DOUBLE(item);
+ Py_DECREF(item);
+ continue;
+ }
+ if (PyLong_Check(item)) {
+ long value;
+ int overflow;
+ value = PyLong_AsLongAndOverflow(item, &overflow);
+ if (!overflow) {
+ f_result += (double)value;
+ Py_DECREF(item);
+ continue;
+ }
+ }
+ result = PyFloat_FromDouble(f_result);
+ if (result == NULL) {
+ Py_DECREF(item);
+ Py_DECREF(iter);
+ return NULL;
+ }
+ temp = PyNumber_Add(result, item);
+ Py_DECREF(result);
+ Py_DECREF(item);
+ result = temp;
+ if (result == NULL) {
+ Py_DECREF(iter);
+ return NULL;
+ }
+ }
+ }
+#endif
+
+ for(;;) {
+ item = PyIter_Next(iter);
+ if (item == NULL) {
+ /* error, or end-of-sequence */
+ if (PyErr_Occurred()) {
+ Py_DECREF(result);
+ result = NULL;
+ }
+ break;
+ }
+ /* It's tempting to use PyNumber_InPlaceAdd instead of
+ PyNumber_Add here, to avoid quadratic running time
+ when doing 'sum(list_of_lists, [])'. However, this
+ would produce a change in behaviour: a snippet like
+
+ empty = []
+ sum([[x] for x in range(10)], empty)
+
+ would change the value of empty. In fact, using
+ in-place addition rather that binary addition for
+ any of the steps introduces subtle behavior changes:
+
+ https://bugs.python.org/issue18305 */
+ temp = PyNumber_Add(result, item);
+ Py_DECREF(result);
+ Py_DECREF(item);
+ result = temp;
+ if (result == NULL)
+ break;
+ }
+ Py_DECREF(iter);
+ return result;
+}
+
+
+/*[clinic input]
+isinstance as builtin_isinstance
+
+ obj: object
+ class_or_tuple: object
+ /
+
+Return whether an object is an instance of a class or of a subclass thereof.
+
+A tuple, as in ``isinstance(x, (A, B, ...))``, may be given as the target to
+check against. This is equivalent to ``isinstance(x, A) or isinstance(x, B)
+or ...`` etc.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_isinstance_impl(PyObject *module, PyObject *obj,
+ PyObject *class_or_tuple)
+/*[clinic end generated code: output=6faf01472c13b003 input=ffa743db1daf7549]*/
+{
+ int retval;
+
+ retval = PyObject_IsInstance(obj, class_or_tuple);
+ if (retval < 0)
+ return NULL;
+ return PyBool_FromLong(retval);
+}
+
+
+/*[clinic input]
+issubclass as builtin_issubclass
+
+ cls: object
+ class_or_tuple: object
+ /
+
+Return whether 'cls' is a derived from another class or is the same class.
+
+A tuple, as in ``issubclass(x, (A, B, ...))``, may be given as the target to
+check against. This is equivalent to ``issubclass(x, A) or issubclass(x, B)
+or ...`` etc.
+[clinic start generated code]*/
+
+static PyObject *
+builtin_issubclass_impl(PyObject *module, PyObject *cls,
+ PyObject *class_or_tuple)
+/*[clinic end generated code: output=358412410cd7a250 input=af5f35e9ceaddaf6]*/
+{
+ int retval;
+
+ retval = PyObject_IsSubclass(cls, class_or_tuple);
+ if (retval < 0)
+ return NULL;
+ return PyBool_FromLong(retval);
+}
+
+
+typedef struct {
+ PyObject_HEAD
+ Py_ssize_t tuplesize;
+ PyObject *ittuple; /* tuple of iterators */
+ PyObject *result;
+} zipobject;
+
+static PyObject *
+zip_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ zipobject *lz;
+ Py_ssize_t i;
+ PyObject *ittuple; /* tuple of iterators */
+ PyObject *result;
+ Py_ssize_t tuplesize;
+
+ if (type == &PyZip_Type && !_PyArg_NoKeywords("zip", kwds))
+ return NULL;
+
+ /* args must be a tuple */
+ assert(PyTuple_Check(args));
+ tuplesize = PyTuple_GET_SIZE(args);
+
+ /* obtain iterators */
+ ittuple = PyTuple_New(tuplesize);
+ if (ittuple == NULL)
+ return NULL;
+ for (i=0; i < tuplesize; ++i) {
+ PyObject *item = PyTuple_GET_ITEM(args, i);
+ PyObject *it = PyObject_GetIter(item);
+ if (it == NULL) {
+ Py_DECREF(ittuple);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(ittuple, i, it);
+ }
+
+ /* create a result holder */
+ result = PyTuple_New(tuplesize);
+ if (result == NULL) {
+ Py_DECREF(ittuple);
+ return NULL;
+ }
+ for (i=0 ; i < tuplesize ; i++) {
+ Py_INCREF(Py_None);
+ PyTuple_SET_ITEM(result, i, Py_None);
+ }
+
+ /* create zipobject structure */
+ lz = (zipobject *)type->tp_alloc(type, 0);
+ if (lz == NULL) {
+ Py_DECREF(ittuple);
+ Py_DECREF(result);
+ return NULL;
+ }
+ lz->ittuple = ittuple;
+ lz->tuplesize = tuplesize;
+ lz->result = result;
+
+ return (PyObject *)lz;
+}
+
+static void
+zip_dealloc(zipobject *lz)
+{
+ PyObject_GC_UnTrack(lz);
+ Py_XDECREF(lz->ittuple);
+ Py_XDECREF(lz->result);
+ Py_TYPE(lz)->tp_free(lz);
+}
+
+static int
+zip_traverse(zipobject *lz, visitproc visit, void *arg)
+{
+ Py_VISIT(lz->ittuple);
+ Py_VISIT(lz->result);
+ return 0;
+}
+
+static PyObject *
+zip_next(zipobject *lz)
+{
+ Py_ssize_t i;
+ Py_ssize_t tuplesize = lz->tuplesize;
+ PyObject *result = lz->result;
+ PyObject *it;
+ PyObject *item;
+ PyObject *olditem;
+
+ if (tuplesize == 0)
+ return NULL;
+ if (Py_REFCNT(result) == 1) {
+ Py_INCREF(result);
+ for (i=0 ; i < tuplesize ; i++) {
+ it = PyTuple_GET_ITEM(lz->ittuple, i);
+ item = (*Py_TYPE(it)->tp_iternext)(it);
+ if (item == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ olditem = PyTuple_GET_ITEM(result, i);
+ PyTuple_SET_ITEM(result, i, item);
+ Py_DECREF(olditem);
+ }
+ // bpo-42536: The GC may have untracked this result tuple. Since we're
+ // recycling it, make sure it's tracked again:
+ if (!_PyObject_GC_IS_TRACKED(result)) {
+ _PyObject_GC_TRACK(result);
+ }
+ } else {
+ result = PyTuple_New(tuplesize);
+ if (result == NULL)
+ return NULL;
+ for (i=0 ; i < tuplesize ; i++) {
+ it = PyTuple_GET_ITEM(lz->ittuple, i);
+ item = (*Py_TYPE(it)->tp_iternext)(it);
+ if (item == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(result, i, item);
+ }
+ }
+ return result;
+}
+
+static PyObject *
+zip_reduce(zipobject *lz, PyObject *Py_UNUSED(ignored))
+{
+ /* Just recreate the zip with the internal iterator tuple */
+ return Py_BuildValue("OO", Py_TYPE(lz), lz->ittuple);
+}
+
+static PyMethodDef zip_methods[] = {
+ {"__reduce__", (PyCFunction)zip_reduce, METH_NOARGS, reduce_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+PyDoc_STRVAR(zip_doc,
+"zip(*iterables) --> A zip object yielding tuples until an input is exhausted.\n\
+\n\
+ >>> list(zip('abcdefg', range(3), range(4)))\n\
+ [('a', 0, 0), ('b', 1, 1), ('c', 2, 2)]\n\
+\n\
+The zip object yields n-length tuples, where n is the number of iterables\n\
+passed as positional arguments to zip(). The i-th element in every tuple\n\
+comes from the i-th iterable argument to zip(). This continues until the\n\
+shortest argument is exhausted.");
+
+PyTypeObject PyZip_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "zip", /* tp_name */
+ sizeof(zipobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)zip_dealloc, /* tp_dealloc */
+ 0, /* tp_vectorcall_offset */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_as_async */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ zip_doc, /* tp_doc */
+ (traverseproc)zip_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)zip_next, /* tp_iternext */
+ zip_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ zip_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+
+static PyMethodDef builtin_methods[] = {
+ {"__build_class__", (PyCFunction)(void(*)(void))builtin___build_class__,
+ METH_FASTCALL | METH_KEYWORDS, build_class_doc},
+ {"__import__", (PyCFunction)(void(*)(void))builtin___import__, METH_VARARGS | METH_KEYWORDS, import_doc},
+ BUILTIN_ABS_METHODDEF
+ BUILTIN_ALL_METHODDEF
+ BUILTIN_ANY_METHODDEF
+ BUILTIN_ASCII_METHODDEF
+ BUILTIN_BIN_METHODDEF
+ {"breakpoint", (PyCFunction)(void(*)(void))builtin_breakpoint, METH_FASTCALL | METH_KEYWORDS, breakpoint_doc},
+ BUILTIN_CALLABLE_METHODDEF
+ BUILTIN_CHR_METHODDEF
+ BUILTIN_COMPILE_METHODDEF
+ BUILTIN_DELATTR_METHODDEF
+ {"dir", builtin_dir, METH_VARARGS, dir_doc},
+ BUILTIN_DIVMOD_METHODDEF
+ BUILTIN_EVAL_METHODDEF
+ BUILTIN_EXEC_METHODDEF
+ BUILTIN_FORMAT_METHODDEF
+ {"getattr", (PyCFunction)(void(*)(void))builtin_getattr, METH_FASTCALL, getattr_doc},
+ BUILTIN_GLOBALS_METHODDEF
+ BUILTIN_HASATTR_METHODDEF
+ BUILTIN_HASH_METHODDEF
+ BUILTIN_HEX_METHODDEF
+ BUILTIN_ID_METHODDEF
+ BUILTIN_INPUT_METHODDEF
+ BUILTIN_ISINSTANCE_METHODDEF
+ BUILTIN_ISSUBCLASS_METHODDEF
+ {"iter", (PyCFunction)(void(*)(void))builtin_iter, METH_FASTCALL, iter_doc},
+ BUILTIN_LEN_METHODDEF
+ BUILTIN_LOCALS_METHODDEF
+ {"max", (PyCFunction)(void(*)(void))builtin_max, METH_VARARGS | METH_KEYWORDS, max_doc},
+ {"min", (PyCFunction)(void(*)(void))builtin_min, METH_VARARGS | METH_KEYWORDS, min_doc},
+ {"next", (PyCFunction)(void(*)(void))builtin_next, METH_FASTCALL, next_doc},
+ BUILTIN_OCT_METHODDEF
+ BUILTIN_ORD_METHODDEF
+ BUILTIN_POW_METHODDEF
+ {"print", (PyCFunction)(void(*)(void))builtin_print, METH_FASTCALL | METH_KEYWORDS, print_doc},
+ BUILTIN_REPR_METHODDEF
+ BUILTIN_ROUND_METHODDEF
+ BUILTIN_SETATTR_METHODDEF
+ BUILTIN_SORTED_METHODDEF
+ BUILTIN_SUM_METHODDEF
+ {"vars", builtin_vars, METH_VARARGS, vars_doc},
+ {NULL, NULL},
+};
+
+PyDoc_STRVAR(builtin_doc,
+"Built-in functions, exceptions, and other objects.\n\
+\n\
+Noteworthy: None is the `nil' object; Ellipsis represents `...' in slices.");
+
+static struct PyModuleDef builtinsmodule = {
+ PyModuleDef_HEAD_INIT,
+ "builtins",
+ builtin_doc,
+ -1, /* multiple "initialization" just copies the module dict. */
+ builtin_methods,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+
+PyObject *
+_PyBuiltin_Init(PyThreadState *tstate)
+{
+ PyObject *mod, *dict, *debug;
+
+ const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
+
+ if (PyType_Ready(&PyFilter_Type) < 0 ||
+ PyType_Ready(&PyMap_Type) < 0 ||
+ PyType_Ready(&PyZip_Type) < 0)
+ return NULL;
+
+ mod = _PyModule_CreateInitialized(&builtinsmodule, PYTHON_API_VERSION);
+ if (mod == NULL)
+ return NULL;
+ dict = PyModule_GetDict(mod);
+
+#ifdef Py_TRACE_REFS
+ /* "builtins" exposes a number of statically allocated objects
+ * that, before this code was added in 2.3, never showed up in
+ * the list of "all objects" maintained by Py_TRACE_REFS. As a
+ * result, programs leaking references to None and False (etc)
+ * couldn't be diagnosed by examining sys.getobjects(0).
+ */
+#define ADD_TO_ALL(OBJECT) _Py_AddToAllObjects((PyObject *)(OBJECT), 0)
+#else
+#define ADD_TO_ALL(OBJECT) (void)0
+#endif
+
+#define SETBUILTIN(NAME, OBJECT) \
+ if (PyDict_SetItemString(dict, NAME, (PyObject *)OBJECT) < 0) \
+ return NULL; \
+ ADD_TO_ALL(OBJECT)
+
+ SETBUILTIN("None", Py_None);
+ SETBUILTIN("Ellipsis", Py_Ellipsis);
+ SETBUILTIN("NotImplemented", Py_NotImplemented);
+ SETBUILTIN("False", Py_False);
+ SETBUILTIN("True", Py_True);
+ SETBUILTIN("bool", &PyBool_Type);
+ SETBUILTIN("memoryview", &PyMemoryView_Type);
+ SETBUILTIN("bytearray", &PyByteArray_Type);
+ SETBUILTIN("bytes", &PyBytes_Type);
+ SETBUILTIN("classmethod", &PyClassMethod_Type);
+ SETBUILTIN("complex", &PyComplex_Type);
+ SETBUILTIN("dict", &PyDict_Type);
+ SETBUILTIN("enumerate", &PyEnum_Type);
+ SETBUILTIN("filter", &PyFilter_Type);
+ SETBUILTIN("float", &PyFloat_Type);
+ SETBUILTIN("frozenset", &PyFrozenSet_Type);
+ SETBUILTIN("property", &PyProperty_Type);
+ SETBUILTIN("int", &PyLong_Type);
+ SETBUILTIN("list", &PyList_Type);
+ SETBUILTIN("map", &PyMap_Type);
+ SETBUILTIN("object", &PyBaseObject_Type);
+ SETBUILTIN("range", &PyRange_Type);
+ SETBUILTIN("reversed", &PyReversed_Type);
+ SETBUILTIN("set", &PySet_Type);
+ SETBUILTIN("slice", &PySlice_Type);
+ SETBUILTIN("staticmethod", &PyStaticMethod_Type);
+ SETBUILTIN("str", &PyUnicode_Type);
+ SETBUILTIN("super", &PySuper_Type);
+ SETBUILTIN("tuple", &PyTuple_Type);
+ SETBUILTIN("type", &PyType_Type);
+ SETBUILTIN("zip", &PyZip_Type);
+ debug = PyBool_FromLong(config->optimization_level == 0);
+ if (PyDict_SetItemString(dict, "__debug__", debug) < 0) {
+ Py_DECREF(debug);
+ return NULL;
+ }
+ Py_DECREF(debug);
+
+ return mod;
+#undef ADD_TO_ALL
+#undef SETBUILTIN
+}
diff --git a/contrib/tools/python3/src/Python/bootstrap_hash.c b/contrib/tools/python3/src/Python/bootstrap_hash.c
new file mode 100644
index 00000000000..e189ce0d901
--- /dev/null
+++ b/contrib/tools/python3/src/Python/bootstrap_hash.c
@@ -0,0 +1,623 @@
+#include "Python.h"
+#include "pycore_initconfig.h"
+#ifdef MS_WINDOWS
+# include <windows.h>
+/* All sample MSDN wincrypt programs include the header below. It is at least
+ * required with Min GW. */
+# include <wincrypt.h>
+#else
+# include <fcntl.h>
+# ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+# endif
+# ifdef HAVE_LINUX_RANDOM_H
+# include <linux/random.h>
+# endif
+# if defined(HAVE_SYS_RANDOM_H) && (defined(HAVE_GETRANDOM) || defined(HAVE_GETENTROPY))
+# include <sys/random.h>
+# endif
+# if !defined(HAVE_GETRANDOM) && defined(HAVE_GETRANDOM_SYSCALL)
+# include <sys/syscall.h>
+# endif
+#endif
+
+#ifdef _Py_MEMORY_SANITIZER
+# include <sanitizer/msan_interface.h>
+#endif
+
+#if defined(__APPLE__) && defined(__has_builtin)
+# if __has_builtin(__builtin_available)
+# define HAVE_GETENTRYPY_GETRANDOM_RUNTIME __builtin_available(macOS 10.12, iOS 10.10, tvOS 10.0, watchOS 3.0, *)
+# endif
+#endif
+#ifndef HAVE_GETENTRYPY_GETRANDOM_RUNTIME
+# define HAVE_GETENTRYPY_GETRANDOM_RUNTIME 1
+#endif
+
+
+#ifdef Py_DEBUG
+int _Py_HashSecret_Initialized = 0;
+#else
+static int _Py_HashSecret_Initialized = 0;
+#endif
+
+#ifdef MS_WINDOWS
+static HCRYPTPROV hCryptProv = 0;
+
+static int
+win32_urandom_init(int raise)
+{
+ /* Acquire context */
+ if (!CryptAcquireContextW(&hCryptProv, NULL, NULL,
+ PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
+ goto error;
+
+ return 0;
+
+error:
+ if (raise) {
+ PyErr_SetFromWindowsErr(0);
+ }
+ return -1;
+}
+
+/* Fill buffer with size pseudo-random bytes generated by the Windows CryptoGen
+ API. Return 0 on success, or raise an exception and return -1 on error. */
+static int
+win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
+{
+ if (hCryptProv == 0)
+ {
+ if (win32_urandom_init(raise) == -1) {
+ return -1;
+ }
+ }
+
+ while (size > 0)
+ {
+ DWORD chunk = (DWORD)Py_MIN(size, PY_DWORD_MAX);
+ if (!CryptGenRandom(hCryptProv, chunk, buffer))
+ {
+ /* CryptGenRandom() failed */
+ if (raise) {
+ PyErr_SetFromWindowsErr(0);
+ }
+ return -1;
+ }
+ buffer += chunk;
+ size -= chunk;
+ }
+ return 0;
+}
+
+#else /* !MS_WINDOWS */
+
+#if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL)
+#define PY_GETRANDOM 1
+
+/* Call getrandom() to get random bytes:
+
+ - Return 1 on success
+ - Return 0 if getrandom() is not available (failed with ENOSYS or EPERM),
+ or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom not
+ initialized yet) and raise=0.
+ - Raise an exception (if raise is non-zero) and return -1 on error:
+ if getrandom() failed with EINTR, raise is non-zero and the Python signal
+ handler raised an exception, or if getrandom() failed with a different
+ error.
+
+ getrandom() is retried if it failed with EINTR: interrupted by a signal. */
+static int
+py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise)
+{
+ /* Is getrandom() supported by the running kernel? Set to 0 if getrandom()
+ failed with ENOSYS or EPERM. Need Linux kernel 3.17 or newer, or Solaris
+ 11.3 or newer */
+ static int getrandom_works = 1;
+ int flags;
+ char *dest;
+ long n;
+
+ if (!getrandom_works) {
+ return 0;
+ }
+
+ flags = blocking ? 0 : GRND_NONBLOCK;
+ dest = buffer;
+ while (0 < size) {
+#if defined(__sun) && defined(__SVR4)
+ /* Issue #26735: On Solaris, getrandom() is limited to returning up
+ to 1024 bytes. Call it multiple times if more bytes are
+ requested. */
+ n = Py_MIN(size, 1024);
+#else
+ n = Py_MIN(size, LONG_MAX);
+#endif
+
+ errno = 0;
+#ifdef HAVE_GETRANDOM
+ if (raise) {
+ Py_BEGIN_ALLOW_THREADS
+ n = getrandom(dest, n, flags);
+ Py_END_ALLOW_THREADS
+ }
+ else {
+ n = getrandom(dest, n, flags);
+ }
+#else
+ /* On Linux, use the syscall() function because the GNU libc doesn't
+ expose the Linux getrandom() syscall yet. See:
+ https://sourceware.org/bugzilla/show_bug.cgi?id=17252 */
+ if (raise) {
+ Py_BEGIN_ALLOW_THREADS
+ n = syscall(SYS_getrandom, dest, n, flags);
+ Py_END_ALLOW_THREADS
+ }
+ else {
+ n = syscall(SYS_getrandom, dest, n, flags);
+ }
+# ifdef _Py_MEMORY_SANITIZER
+ if (n > 0) {
+ __msan_unpoison(dest, n);
+ }
+# endif
+#endif
+
+ if (n < 0) {
+ /* ENOSYS: the syscall is not supported by the kernel.
+ EPERM: the syscall is blocked by a security policy (ex: SECCOMP)
+ or something else. */
+ if (errno == ENOSYS || errno == EPERM) {
+ getrandom_works = 0;
+ return 0;
+ }
+
+ /* getrandom(GRND_NONBLOCK) fails with EAGAIN if the system urandom
+ is not initialized yet. For _PyRandom_Init(), we ignore the
+ error and fall back on reading /dev/urandom which never blocks,
+ even if the system urandom is not initialized yet:
+ see the PEP 524. */
+ if (errno == EAGAIN && !raise && !blocking) {
+ return 0;
+ }
+
+ if (errno == EINTR) {
+ if (raise) {
+ if (PyErr_CheckSignals()) {
+ return -1;
+ }
+ }
+
+ /* retry getrandom() if it was interrupted by a signal */
+ continue;
+ }
+
+ if (raise) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ }
+ return -1;
+ }
+
+ dest += n;
+ size -= n;
+ }
+ return 1;
+}
+
+#elif defined(HAVE_GETENTROPY)
+#define PY_GETENTROPY 1
+
+/* Fill buffer with size pseudo-random bytes generated by getentropy():
+
+ - Return 1 on success
+ - Return 0 if getentropy() syscall is not available (failed with ENOSYS or
+ EPERM).
+ - Raise an exception (if raise is non-zero) and return -1 on error:
+ if getentropy() failed with EINTR, raise is non-zero and the Python signal
+ handler raised an exception, or if getentropy() failed with a different
+ error.
+
+ getentropy() is retried if it failed with EINTR: interrupted by a signal. */
+
+#if defined(__APPLE__) && defined(__has_attribute) && __has_attribute(availability)
+static int
+py_getentropy(char *buffer, Py_ssize_t size, int raise)
+ __attribute__((availability(macos,introduced=10.12)))
+ __attribute__((availability(ios,introduced=10.0)))
+ __attribute__((availability(tvos,introduced=10.0)))
+ __attribute__((availability(watchos,introduced=3.0)));
+#endif
+
+static int
+py_getentropy(char *buffer, Py_ssize_t size, int raise)
+{
+ /* Is getentropy() supported by the running kernel? Set to 0 if
+ getentropy() failed with ENOSYS or EPERM. */
+ static int getentropy_works = 1;
+
+ if (!getentropy_works) {
+ return 0;
+ }
+
+ while (size > 0) {
+ /* getentropy() is limited to returning up to 256 bytes. Call it
+ multiple times if more bytes are requested. */
+ Py_ssize_t len = Py_MIN(size, 256);
+ int res;
+
+ if (raise) {
+ Py_BEGIN_ALLOW_THREADS
+ res = getentropy(buffer, len);
+ Py_END_ALLOW_THREADS
+ }
+ else {
+ res = getentropy(buffer, len);
+ }
+
+ if (res < 0) {
+ /* ENOSYS: the syscall is not supported by the running kernel.
+ EPERM: the syscall is blocked by a security policy (ex: SECCOMP)
+ or something else. */
+ if (errno == ENOSYS || errno == EPERM) {
+ getentropy_works = 0;
+ return 0;
+ }
+
+ if (errno == EINTR) {
+ if (raise) {
+ if (PyErr_CheckSignals()) {
+ return -1;
+ }
+ }
+
+ /* retry getentropy() if it was interrupted by a signal */
+ continue;
+ }
+
+ if (raise) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ }
+ return -1;
+ }
+
+ buffer += len;
+ size -= len;
+ }
+ return 1;
+}
+#endif /* defined(HAVE_GETENTROPY) && !(defined(__sun) && defined(__SVR4)) */
+
+
+static struct {
+ int fd;
+ dev_t st_dev;
+ ino_t st_ino;
+} urandom_cache = { -1 };
+
+/* Read random bytes from the /dev/urandom device:
+
+ - Return 0 on success
+ - Raise an exception (if raise is non-zero) and return -1 on error
+
+ Possible causes of errors:
+
+ - open() failed with ENOENT, ENXIO, ENODEV, EACCES: the /dev/urandom device
+ was not found. For example, it was removed manually or not exposed in a
+ chroot or container.
+ - open() failed with a different error
+ - fstat() failed
+ - read() failed or returned 0
+
+ read() is retried if it failed with EINTR: interrupted by a signal.
+
+ The file descriptor of the device is kept open between calls to avoid using
+ many file descriptors when run in parallel from multiple threads:
+ see the issue #18756.
+
+ st_dev and st_ino fields of the file descriptor (from fstat()) are cached to
+ check if the file descriptor was replaced by a different file (which is
+ likely a bug in the application): see the issue #21207.
+
+ If the file descriptor was closed or replaced, open a new file descriptor
+ but don't close the old file descriptor: it probably points to something
+ important for some third-party code. */
+static int
+dev_urandom(char *buffer, Py_ssize_t size, int raise)
+{
+ int fd;
+ Py_ssize_t n;
+
+ if (raise) {
+ struct _Py_stat_struct st;
+ int fstat_result;
+
+ if (urandom_cache.fd >= 0) {
+ Py_BEGIN_ALLOW_THREADS
+ fstat_result = _Py_fstat_noraise(urandom_cache.fd, &st);
+ Py_END_ALLOW_THREADS
+
+ /* Does the fd point to the same thing as before? (issue #21207) */
+ if (fstat_result
+ || st.st_dev != urandom_cache.st_dev
+ || st.st_ino != urandom_cache.st_ino) {
+ /* Something changed: forget the cached fd (but don't close it,
+ since it probably points to something important for some
+ third-party code). */
+ urandom_cache.fd = -1;
+ }
+ }
+ if (urandom_cache.fd >= 0)
+ fd = urandom_cache.fd;
+ else {
+ fd = _Py_open("/dev/urandom", O_RDONLY);
+ if (fd < 0) {
+ if (errno == ENOENT || errno == ENXIO ||
+ errno == ENODEV || errno == EACCES) {
+ PyErr_SetString(PyExc_NotImplementedError,
+ "/dev/urandom (or equivalent) not found");
+ }
+ /* otherwise, keep the OSError exception raised by _Py_open() */
+ return -1;
+ }
+ if (urandom_cache.fd >= 0) {
+ /* urandom_fd was initialized by another thread while we were
+ not holding the GIL, keep it. */
+ close(fd);
+ fd = urandom_cache.fd;
+ }
+ else {
+ if (_Py_fstat(fd, &st)) {
+ close(fd);
+ return -1;
+ }
+ else {
+ urandom_cache.fd = fd;
+ urandom_cache.st_dev = st.st_dev;
+ urandom_cache.st_ino = st.st_ino;
+ }
+ }
+ }
+
+ do {
+ n = _Py_read(fd, buffer, (size_t)size);
+ if (n == -1)
+ return -1;
+ if (n == 0) {
+ PyErr_Format(PyExc_RuntimeError,
+ "Failed to read %zi bytes from /dev/urandom",
+ size);
+ return -1;
+ }
+
+ buffer += n;
+ size -= n;
+ } while (0 < size);
+ }
+ else {
+ fd = _Py_open_noraise("/dev/urandom", O_RDONLY);
+ if (fd < 0) {
+ return -1;
+ }
+
+ while (0 < size)
+ {
+ do {
+ n = read(fd, buffer, (size_t)size);
+ } while (n < 0 && errno == EINTR);
+
+ if (n <= 0) {
+ /* stop on error or if read(size) returned 0 */
+ close(fd);
+ return -1;
+ }
+
+ buffer += n;
+ size -= n;
+ }
+ close(fd);
+ }
+ return 0;
+}
+
+static void
+dev_urandom_close(void)
+{
+ if (urandom_cache.fd >= 0) {
+ close(urandom_cache.fd);
+ urandom_cache.fd = -1;
+ }
+}
+#endif /* !MS_WINDOWS */
+
+
+/* Fill buffer with pseudo-random bytes generated by a linear congruent
+ generator (LCG):
+
+ x(n+1) = (x(n) * 214013 + 2531011) % 2^32
+
+ Use bits 23..16 of x(n) to generate a byte. */
+static void
+lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size)
+{
+ size_t index;
+ unsigned int x;
+
+ x = x0;
+ for (index=0; index < size; index++) {
+ x *= 214013;
+ x += 2531011;
+ /* modulo 2 ^ (8 * sizeof(int)) */
+ buffer[index] = (x >> 16) & 0xff;
+ }
+}
+
+/* Read random bytes:
+
+ - Return 0 on success
+ - Raise an exception (if raise is non-zero) and return -1 on error
+
+ Used sources of entropy ordered by preference, preferred source first:
+
+ - CryptGenRandom() on Windows
+ - getrandom() function (ex: Linux and Solaris): call py_getrandom()
+ - getentropy() function (ex: OpenBSD): call py_getentropy()
+ - /dev/urandom device
+
+ Read from the /dev/urandom device if getrandom() or getentropy() function
+ is not available or does not work.
+
+ Prefer getrandom() over getentropy() because getrandom() supports blocking
+ and non-blocking mode: see the PEP 524. Python requires non-blocking RNG at
+ startup to initialize its hash secret, but os.urandom() must block until the
+ system urandom is initialized (at least on Linux 3.17 and newer).
+
+ Prefer getrandom() and getentropy() over reading directly /dev/urandom
+ because these functions don't need file descriptors and so avoid ENFILE or
+ EMFILE errors (too many open files): see the issue #18756.
+
+ Only the getrandom() function supports non-blocking mode.
+
+ Only use RNG running in the kernel. They are more secure because it is
+ harder to get the internal state of a RNG running in the kernel land than a
+ RNG running in the user land. The kernel has a direct access to the hardware
+ and has access to hardware RNG, they are used as entropy sources.
+
+ Note: the OpenSSL RAND_pseudo_bytes() function does not automatically reseed
+ its RNG on fork(), two child processes (with the same pid) generate the same
+ random numbers: see issue #18747. Kernel RNGs don't have this issue,
+ they have access to good quality entropy sources.
+
+ If raise is zero:
+
+ - Don't raise an exception on error
+ - Don't call the Python signal handler (don't call PyErr_CheckSignals()) if
+ a function fails with EINTR: retry directly the interrupted function
+ - Don't release the GIL to call functions.
+*/
+static int
+pyurandom(void *buffer, Py_ssize_t size, int blocking, int raise)
+{
+#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY)
+ int res;
+#endif
+
+ if (size < 0) {
+ if (raise) {
+ PyErr_Format(PyExc_ValueError,
+ "negative argument not allowed");
+ }
+ return -1;
+ }
+
+ if (size == 0) {
+ return 0;
+ }
+
+#ifdef MS_WINDOWS
+ return win32_urandom((unsigned char *)buffer, size, raise);
+#else
+
+#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY)
+ if (HAVE_GETENTRYPY_GETRANDOM_RUNTIME) {
+#ifdef PY_GETRANDOM
+ res = py_getrandom(buffer, size, blocking, raise);
+#else
+ res = py_getentropy(buffer, size, raise);
+#endif
+ if (res < 0) {
+ return -1;
+ }
+ if (res == 1) {
+ return 0;
+ }
+ /* getrandom() or getentropy() function is not available: failed with
+ ENOSYS or EPERM. Fall back on reading from /dev/urandom. */
+ } /* end of availability block */
+#endif
+
+ return dev_urandom(buffer, size, raise);
+#endif
+}
+
+/* Fill buffer with size pseudo-random bytes from the operating system random
+ number generator (RNG). It is suitable for most cryptographic purposes
+ except long living private keys for asymmetric encryption.
+
+ On Linux 3.17 and newer, the getrandom() syscall is used in blocking mode:
+ block until the system urandom entropy pool is initialized (128 bits are
+ collected by the kernel).
+
+ Return 0 on success. Raise an exception and return -1 on error. */
+int
+_PyOS_URandom(void *buffer, Py_ssize_t size)
+{
+ return pyurandom(buffer, size, 1, 1);
+}
+
+/* Fill buffer with size pseudo-random bytes from the operating system random
+ number generator (RNG). It is not suitable for cryptographic purpose.
+
+ On Linux 3.17 and newer (when getrandom() syscall is used), if the system
+ urandom is not initialized yet, the function returns "weak" entropy read
+ from /dev/urandom.
+
+ Return 0 on success. Raise an exception and return -1 on error. */
+int
+_PyOS_URandomNonblock(void *buffer, Py_ssize_t size)
+{
+ return pyurandom(buffer, size, 0, 1);
+}
+
+
+PyStatus
+_Py_HashRandomization_Init(const PyConfig *config)
+{
+ void *secret = &_Py_HashSecret;
+ Py_ssize_t secret_size = sizeof(_Py_HashSecret_t);
+
+ if (_Py_HashSecret_Initialized) {
+ return _PyStatus_OK();
+ }
+ _Py_HashSecret_Initialized = 1;
+
+ if (config->use_hash_seed) {
+ if (config->hash_seed == 0) {
+ /* disable the randomized hash */
+ memset(secret, 0, secret_size);
+ }
+ else {
+ /* use the specified hash seed */
+ lcg_urandom(config->hash_seed, secret, secret_size);
+ }
+ }
+ else {
+ /* use a random hash seed */
+ int res;
+
+ /* _PyRandom_Init() is called very early in the Python initialization
+ and so exceptions cannot be used (use raise=0).
+
+ _PyRandom_Init() must not block Python initialization: call
+ pyurandom() is non-blocking mode (blocking=0): see the PEP 524. */
+ res = pyurandom(secret, secret_size, 0, 0);
+ if (res < 0) {
+ return _PyStatus_ERR("failed to get random numbers "
+ "to initialize Python");
+ }
+ }
+ return _PyStatus_OK();
+}
+
+
+void
+_Py_HashRandomization_Fini(void)
+{
+#ifdef MS_WINDOWS
+ if (hCryptProv) {
+ CryptReleaseContext(hCryptProv, 0);
+ hCryptProv = 0;
+ }
+#else
+ dev_urandom_close();
+#endif
+}
diff --git a/contrib/tools/python3/src/Python/ceval.c b/contrib/tools/python3/src/Python/ceval.c
new file mode 100644
index 00000000000..9a61f8a3c3c
--- /dev/null
+++ b/contrib/tools/python3/src/Python/ceval.c
@@ -0,0 +1,5699 @@
+
+/* Execute compiled code */
+
+/* XXX TO DO:
+ XXX speed up searching for keywords by using a dictionary
+ XXX document it!
+ */
+
+/* enable more aggressive intra-module optimizations, where available */
+#define PY_LOCAL_AGGRESSIVE
+
+#include "Python.h"
+#include "pycore_abstract.h" // _PyIndex_Check()
+#include "pycore_call.h"
+#include "pycore_ceval.h"
+#include "pycore_code.h"
+#include "pycore_initconfig.h"
+#include "pycore_object.h"
+#include "pycore_pyerrors.h"
+#include "pycore_pylifecycle.h"
+#include "pycore_pymem.h" // _PyMem_IsPtrFreed()
+#include "pycore_pystate.h" // _PyInterpreterState_GET()
+#include "pycore_sysmodule.h"
+#include "pycore_tupleobject.h"
+
+#include "code.h"
+#include "dictobject.h"
+#include "frameobject.h"
+#include "opcode.h"
+#include "pydtrace.h"
+#include "setobject.h"
+
+#include <ctype.h>
+
+#ifdef Py_DEBUG
+/* For debugging the interpreter: */
+#define LLTRACE 1 /* Low-level trace feature */
+#define CHECKEXC 1 /* Double-check exception checking */
+#endif
+
+#if !defined(Py_BUILD_CORE)
+# error "ceval.c must be build with Py_BUILD_CORE define for best performance"
+#endif
+
+_Py_IDENTIFIER(__name__);
+
+/* Forward declarations */
+Py_LOCAL_INLINE(PyObject *) call_function(
+ PyThreadState *tstate, PyObject ***pp_stack,
+ Py_ssize_t oparg, PyObject *kwnames);
+static PyObject * do_call_core(
+ PyThreadState *tstate, PyObject *func,
+ PyObject *callargs, PyObject *kwdict);
+
+#ifdef LLTRACE
+static int lltrace;
+static int prtrace(PyThreadState *, PyObject *, const char *);
+#endif
+static int call_trace(Py_tracefunc, PyObject *,
+ PyThreadState *, PyFrameObject *,
+ int, PyObject *);
+static int call_trace_protected(Py_tracefunc, PyObject *,
+ PyThreadState *, PyFrameObject *,
+ int, PyObject *);
+static void call_exc_trace(Py_tracefunc, PyObject *,
+ PyThreadState *, PyFrameObject *);
+static int maybe_call_line_trace(Py_tracefunc, PyObject *,
+ PyThreadState *, PyFrameObject *,
+ int *, int *, int *);
+static void maybe_dtrace_line(PyFrameObject *, int *, int *, int *);
+static void dtrace_function_entry(PyFrameObject *);
+static void dtrace_function_return(PyFrameObject *);
+
+static PyObject * import_name(PyThreadState *, PyFrameObject *,
+ PyObject *, PyObject *, PyObject *);
+static PyObject * import_from(PyThreadState *, PyObject *, PyObject *);
+static int import_all_from(PyThreadState *, PyObject *, PyObject *);
+static void format_exc_check_arg(PyThreadState *, PyObject *, const char *, PyObject *);
+static void format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg);
+static PyObject * unicode_concatenate(PyThreadState *, PyObject *, PyObject *,
+ PyFrameObject *, const _Py_CODEUNIT *);
+static PyObject * special_lookup(PyThreadState *, PyObject *, _Py_Identifier *);
+static int check_args_iterable(PyThreadState *, PyObject *func, PyObject *vararg);
+static void format_kwargs_error(PyThreadState *, PyObject *func, PyObject *kwargs);
+static void format_awaitable_error(PyThreadState *, PyTypeObject *, int, int);
+
+#define NAME_ERROR_MSG \
+ "name '%.200s' is not defined"
+#define UNBOUNDLOCAL_ERROR_MSG \
+ "local variable '%.200s' referenced before assignment"
+#define UNBOUNDFREE_ERROR_MSG \
+ "free variable '%.200s' referenced before assignment" \
+ " in enclosing scope"
+
+/* Dynamic execution profile */
+#ifdef DYNAMIC_EXECUTION_PROFILE
+#ifdef DXPAIRS
+static long dxpairs[257][256];
+#define dxp dxpairs[256]
+#else
+static long dxp[256];
+#endif
+#endif
+
+/* per opcode cache */
+#ifdef Py_DEBUG
+// --with-pydebug is used to find memory leak. opcache makes it harder.
+// So we disable opcache when Py_DEBUG is defined.
+// See bpo-37146
+#define OPCACHE_MIN_RUNS 0 /* disable opcache */
+#else
+#define OPCACHE_MIN_RUNS 1024 /* create opcache when code executed this time */
+#endif
+#define OPCACHE_STATS 0 /* Enable stats */
+
+#if OPCACHE_STATS
+static size_t opcache_code_objects = 0;
+static size_t opcache_code_objects_extra_mem = 0;
+
+static size_t opcache_global_opts = 0;
+static size_t opcache_global_hits = 0;
+static size_t opcache_global_misses = 0;
+#endif
+
+
+#ifndef NDEBUG
+/* Ensure that tstate is valid: sanity check for PyEval_AcquireThread() and
+ PyEval_RestoreThread(). Detect if tstate memory was freed. It can happen
+ when a thread continues to run after Python finalization, especially
+ daemon threads. */
+static int
+is_tstate_valid(PyThreadState *tstate)
+{
+ assert(!_PyMem_IsPtrFreed(tstate));
+ assert(!_PyMem_IsPtrFreed(tstate->interp));
+ return 1;
+}
+#endif
+
+
+/* This can set eval_breaker to 0 even though gil_drop_request became
+ 1. We believe this is all right because the eval loop will release
+ the GIL eventually anyway. */
+static inline void
+COMPUTE_EVAL_BREAKER(PyInterpreterState *interp,
+ struct _ceval_runtime_state *ceval,
+ struct _ceval_state *ceval2)
+{
+ _Py_atomic_store_relaxed(&ceval2->eval_breaker,
+ _Py_atomic_load_relaxed(&ceval2->gil_drop_request)
+ | (_Py_atomic_load_relaxed(&ceval->signals_pending)
+ && _Py_ThreadCanHandleSignals(interp))
+ | (_Py_atomic_load_relaxed(&ceval2->pending.calls_to_do)
+ && _Py_ThreadCanHandlePendingCalls())
+ | ceval2->pending.async_exc);
+}
+
+
+static inline void
+SET_GIL_DROP_REQUEST(PyInterpreterState *interp)
+{
+ struct _ceval_state *ceval2 = &interp->ceval;
+ _Py_atomic_store_relaxed(&ceval2->gil_drop_request, 1);
+ _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1);
+}
+
+
+static inline void
+RESET_GIL_DROP_REQUEST(PyInterpreterState *interp)
+{
+ struct _ceval_runtime_state *ceval = &interp->runtime->ceval;
+ struct _ceval_state *ceval2 = &interp->ceval;
+ _Py_atomic_store_relaxed(&ceval2->gil_drop_request, 0);
+ COMPUTE_EVAL_BREAKER(interp, ceval, ceval2);
+}
+
+
+static inline void
+SIGNAL_PENDING_CALLS(PyInterpreterState *interp)
+{
+ struct _ceval_runtime_state *ceval = &interp->runtime->ceval;
+ struct _ceval_state *ceval2 = &interp->ceval;
+ _Py_atomic_store_relaxed(&ceval2->pending.calls_to_do, 1);
+ COMPUTE_EVAL_BREAKER(interp, ceval, ceval2);
+}
+
+
+static inline void
+UNSIGNAL_PENDING_CALLS(PyInterpreterState *interp)
+{
+ struct _ceval_runtime_state *ceval = &interp->runtime->ceval;
+ struct _ceval_state *ceval2 = &interp->ceval;
+ _Py_atomic_store_relaxed(&ceval2->pending.calls_to_do, 0);
+ COMPUTE_EVAL_BREAKER(interp, ceval, ceval2);
+}
+
+
+static inline void
+SIGNAL_PENDING_SIGNALS(PyInterpreterState *interp, int force)
+{
+ struct _ceval_runtime_state *ceval = &interp->runtime->ceval;
+ struct _ceval_state *ceval2 = &interp->ceval;
+ _Py_atomic_store_relaxed(&ceval->signals_pending, 1);
+ if (force) {
+ _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1);
+ }
+ else {
+ /* eval_breaker is not set to 1 if thread_can_handle_signals() is false */
+ COMPUTE_EVAL_BREAKER(interp, ceval, ceval2);
+ }
+}
+
+
+static inline void
+UNSIGNAL_PENDING_SIGNALS(PyInterpreterState *interp)
+{
+ struct _ceval_runtime_state *ceval = &interp->runtime->ceval;
+ struct _ceval_state *ceval2 = &interp->ceval;
+ _Py_atomic_store_relaxed(&ceval->signals_pending, 0);
+ COMPUTE_EVAL_BREAKER(interp, ceval, ceval2);
+}
+
+
+static inline void
+SIGNAL_ASYNC_EXC(PyInterpreterState *interp)
+{
+ struct _ceval_state *ceval2 = &interp->ceval;
+ ceval2->pending.async_exc = 1;
+ _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1);
+}
+
+
+static inline void
+UNSIGNAL_ASYNC_EXC(PyInterpreterState *interp)
+{
+ struct _ceval_runtime_state *ceval = &interp->runtime->ceval;
+ struct _ceval_state *ceval2 = &interp->ceval;
+ ceval2->pending.async_exc = 0;
+ COMPUTE_EVAL_BREAKER(interp, ceval, ceval2);
+}
+
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include "ceval_gil.h"
+
+void _Py_NO_RETURN
+_Py_FatalError_TstateNULL(const char *func)
+{
+ _Py_FatalErrorFunc(func,
+ "the function must be called with the GIL held, "
+ "but the GIL is released "
+ "(the current Python thread state is NULL)");
+}
+
+
+int
+_PyEval_ThreadsInitialized(_PyRuntimeState *runtime)
+{
+ return gil_created(&runtime->ceval.gil);
+}
+
+int
+PyEval_ThreadsInitialized(void)
+{
+ _PyRuntimeState *runtime = &_PyRuntime;
+ return _PyEval_ThreadsInitialized(runtime);
+}
+
+PyStatus
+_PyEval_InitGIL(PyThreadState *tstate)
+{
+ if (!_Py_IsMainInterpreter(tstate)) {
+ /* Currently, the GIL is shared by all interpreters,
+ and only the main interpreter is responsible to create
+ and destroy it. */
+ return _PyStatus_OK();
+ }
+
+ struct _gil_runtime_state *gil = &tstate->interp->runtime->ceval.gil;
+ assert(!gil_created(gil));
+
+ PyThread_init_thread();
+ create_gil(gil);
+
+ take_gil(tstate);
+
+ assert(gil_created(gil));
+ return _PyStatus_OK();
+}
+
+void
+_PyEval_FiniGIL(PyThreadState *tstate)
+{
+ if (!_Py_IsMainInterpreter(tstate)) {
+ /* Currently, the GIL is shared by all interpreters,
+ and only the main interpreter is responsible to create
+ and destroy it. */
+ return;
+ }
+
+ struct _gil_runtime_state *gil = &tstate->interp->runtime->ceval.gil;
+ if (!gil_created(gil)) {
+ /* First Py_InitializeFromConfig() call: the GIL doesn't exist
+ yet: do nothing. */
+ return;
+ }
+
+ destroy_gil(gil);
+ assert(!gil_created(gil));
+}
+
+void
+PyEval_InitThreads(void)
+{
+ /* Do nothing: kept for backward compatibility */
+}
+
+void
+_PyEval_Fini(void)
+{
+#if OPCACHE_STATS
+ fprintf(stderr, "-- Opcode cache number of objects = %zd\n",
+ opcache_code_objects);
+
+ fprintf(stderr, "-- Opcode cache total extra mem = %zd\n",
+ opcache_code_objects_extra_mem);
+
+ fprintf(stderr, "\n");
+
+ fprintf(stderr, "-- Opcode cache LOAD_GLOBAL hits = %zd (%d%%)\n",
+ opcache_global_hits,
+ (int) (100.0 * opcache_global_hits /
+ (opcache_global_hits + opcache_global_misses)));
+
+ fprintf(stderr, "-- Opcode cache LOAD_GLOBAL misses = %zd (%d%%)\n",
+ opcache_global_misses,
+ (int) (100.0 * opcache_global_misses /
+ (opcache_global_hits + opcache_global_misses)));
+
+ fprintf(stderr, "-- Opcode cache LOAD_GLOBAL opts = %zd\n",
+ opcache_global_opts);
+
+ fprintf(stderr, "\n");
+#endif
+}
+
+void
+PyEval_AcquireLock(void)
+{
+ _PyRuntimeState *runtime = &_PyRuntime;
+ PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
+ _Py_EnsureTstateNotNULL(tstate);
+
+ take_gil(tstate);
+}
+
+void
+PyEval_ReleaseLock(void)
+{
+ _PyRuntimeState *runtime = &_PyRuntime;
+ PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
+ /* This function must succeed when the current thread state is NULL.
+ We therefore avoid PyThreadState_Get() which dumps a fatal error
+ in debug mode. */
+ struct _ceval_runtime_state *ceval = &runtime->ceval;
+ struct _ceval_state *ceval2 = &tstate->interp->ceval;
+ drop_gil(ceval, ceval2, tstate);
+}
+
+void
+_PyEval_ReleaseLock(PyThreadState *tstate)
+{
+ struct _ceval_runtime_state *ceval = &tstate->interp->runtime->ceval;
+ struct _ceval_state *ceval2 = &tstate->interp->ceval;
+ drop_gil(ceval, ceval2, tstate);
+}
+
+void
+PyEval_AcquireThread(PyThreadState *tstate)
+{
+ _Py_EnsureTstateNotNULL(tstate);
+
+ take_gil(tstate);
+
+ struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate;
+ if (_PyThreadState_Swap(gilstate, tstate) != NULL) {
+ Py_FatalError("non-NULL old thread state");
+ }
+}
+
+void
+PyEval_ReleaseThread(PyThreadState *tstate)
+{
+ assert(is_tstate_valid(tstate));
+
+ _PyRuntimeState *runtime = tstate->interp->runtime;
+ PyThreadState *new_tstate = _PyThreadState_Swap(&runtime->gilstate, NULL);
+ if (new_tstate != tstate) {
+ Py_FatalError("wrong thread state");
+ }
+ struct _ceval_runtime_state *ceval = &runtime->ceval;
+ struct _ceval_state *ceval2 = &tstate->interp->ceval;
+ drop_gil(ceval, ceval2, tstate);
+}
+
+#ifdef HAVE_FORK
+/* This function is called from PyOS_AfterFork_Child to destroy all threads
+ * which are not running in the child process, and clear internal locks
+ * which might be held by those threads.
+ */
+
+void
+_PyEval_ReInitThreads(_PyRuntimeState *runtime)
+{
+ PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
+ _Py_EnsureTstateNotNULL(tstate);
+
+ struct _gil_runtime_state *gil = &runtime->ceval.gil;
+ if (!gil_created(gil)) {
+ return;
+ }
+ recreate_gil(gil);
+
+ take_gil(tstate);
+
+ struct _pending_calls *pending = &tstate->interp->ceval.pending;
+ if (_PyThread_at_fork_reinit(&pending->lock) < 0) {
+ Py_FatalError("Can't initialize threads for pending calls");
+ }
+
+ /* Destroy all threads except the current one */
+ _PyThreadState_DeleteExcept(runtime, tstate);
+}
+#endif
+
+/* This function is used to signal that async exceptions are waiting to be
+ raised. */
+
+void
+_PyEval_SignalAsyncExc(PyThreadState *tstate)
+{
+ assert(is_tstate_valid(tstate));
+ SIGNAL_ASYNC_EXC(tstate->interp);
+}
+
+PyThreadState *
+PyEval_SaveThread(void)
+{
+ _PyRuntimeState *runtime = &_PyRuntime;
+ PyThreadState *tstate = _PyThreadState_Swap(&runtime->gilstate, NULL);
+ _Py_EnsureTstateNotNULL(tstate);
+
+ struct _ceval_runtime_state *ceval = &runtime->ceval;
+ struct _ceval_state *ceval2 = &tstate->interp->ceval;
+ assert(gil_created(&ceval->gil));
+ drop_gil(ceval, ceval2, tstate);
+ return tstate;
+}
+
+void
+PyEval_RestoreThread(PyThreadState *tstate)
+{
+ _Py_EnsureTstateNotNULL(tstate);
+
+ take_gil(tstate);
+
+ struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate;
+ _PyThreadState_Swap(gilstate, tstate);
+}
+
+
+/* Mechanism whereby asynchronously executing callbacks (e.g. UNIX
+ signal handlers or Mac I/O completion routines) can schedule calls
+ to a function to be called synchronously.
+ The synchronous function is called with one void* argument.
+ It should return 0 for success or -1 for failure -- failure should
+ be accompanied by an exception.
+
+ If registry succeeds, the registry function returns 0; if it fails
+ (e.g. due to too many pending calls) it returns -1 (without setting
+ an exception condition).
+
+ Note that because registry may occur from within signal handlers,
+ or other asynchronous events, calling malloc() is unsafe!
+
+ Any thread can schedule pending calls, but only the main thread
+ will execute them.
+ There is no facility to schedule calls to a particular thread, but
+ that should be easy to change, should that ever be required. In
+ that case, the static variables here should go into the python
+ threadstate.
+*/
+
+void
+_PyEval_SignalReceived(PyInterpreterState *interp)
+{
+#ifdef MS_WINDOWS
+ // bpo-42296: On Windows, _PyEval_SignalReceived() is called from a signal
+ // handler which can run in a thread different than the Python thread, in
+ // which case _Py_ThreadCanHandleSignals() is wrong. Ignore
+ // _Py_ThreadCanHandleSignals() and always set eval_breaker to 1.
+ //
+ // The next eval_frame_handle_pending() call will call
+ // _Py_ThreadCanHandleSignals() to recompute eval_breaker.
+ int force = 1;
+#else
+ int force = 0;
+#endif
+ /* bpo-30703: Function called when the C signal handler of Python gets a
+ signal. We cannot queue a callback using _PyEval_AddPendingCall() since
+ that function is not async-signal-safe. */
+ SIGNAL_PENDING_SIGNALS(interp, force);
+}
+
+/* Push one item onto the queue while holding the lock. */
+static int
+_push_pending_call(struct _pending_calls *pending,
+ int (*func)(void *), void *arg)
+{
+ int i = pending->last;
+ int j = (i + 1) % NPENDINGCALLS;
+ if (j == pending->first) {
+ return -1; /* Queue full */
+ }
+ pending->calls[i].func = func;
+ pending->calls[i].arg = arg;
+ pending->last = j;
+ return 0;
+}
+
+/* Pop one item off the queue while holding the lock. */
+static void
+_pop_pending_call(struct _pending_calls *pending,
+ int (**func)(void *), void **arg)
+{
+ int i = pending->first;
+ if (i == pending->last) {
+ return; /* Queue empty */
+ }
+
+ *func = pending->calls[i].func;
+ *arg = pending->calls[i].arg;
+ pending->first = (i + 1) % NPENDINGCALLS;
+}
+
+/* This implementation is thread-safe. It allows
+ scheduling to be made from any thread, and even from an executing
+ callback.
+ */
+
+int
+_PyEval_AddPendingCall(PyInterpreterState *interp,
+ int (*func)(void *), void *arg)
+{
+ struct _pending_calls *pending = &interp->ceval.pending;
+
+ /* Ensure that _PyEval_InitPendingCalls() was called
+ and that _PyEval_FiniPendingCalls() is not called yet. */
+ assert(pending->lock != NULL);
+
+ PyThread_acquire_lock(pending->lock, WAIT_LOCK);
+ int result = _push_pending_call(pending, func, arg);
+ PyThread_release_lock(pending->lock);
+
+ /* signal main loop */
+ SIGNAL_PENDING_CALLS(interp);
+ return result;
+}
+
+int
+Py_AddPendingCall(int (*func)(void *), void *arg)
+{
+ /* Best-effort to support subinterpreters and calls with the GIL released.
+
+ First attempt _PyThreadState_GET() since it supports subinterpreters.
+
+ If the GIL is released, _PyThreadState_GET() returns NULL . In this
+ case, use PyGILState_GetThisThreadState() which works even if the GIL
+ is released.
+
+ Sadly, PyGILState_GetThisThreadState() doesn't support subinterpreters:
+ see bpo-10915 and bpo-15751.
+
+ Py_AddPendingCall() doesn't require the caller to hold the GIL. */
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (tstate == NULL) {
+ tstate = PyGILState_GetThisThreadState();
+ }
+
+ PyInterpreterState *interp;
+ if (tstate != NULL) {
+ interp = tstate->interp;
+ }
+ else {
+ /* Last resort: use the main interpreter */
+ interp = _PyRuntime.interpreters.main;
+ }
+ return _PyEval_AddPendingCall(interp, func, arg);
+}
+
+static int
+handle_signals(PyThreadState *tstate)
+{
+ assert(is_tstate_valid(tstate));
+ if (!_Py_ThreadCanHandleSignals(tstate->interp)) {
+ return 0;
+ }
+
+ UNSIGNAL_PENDING_SIGNALS(tstate->interp);
+ if (_PyErr_CheckSignalsTstate(tstate) < 0) {
+ /* On failure, re-schedule a call to handle_signals(). */
+ SIGNAL_PENDING_SIGNALS(tstate->interp, 0);
+ return -1;
+ }
+ return 0;
+}
+
+static int
+make_pending_calls(PyThreadState *tstate)
+{
+ assert(is_tstate_valid(tstate));
+
+ /* only execute pending calls on main thread */
+ if (!_Py_ThreadCanHandlePendingCalls()) {
+ return 0;
+ }
+
+ /* don't perform recursive pending calls */
+ static int busy = 0;
+ if (busy) {
+ return 0;
+ }
+ busy = 1;
+
+ /* unsignal before starting to call callbacks, so that any callback
+ added in-between re-signals */
+ UNSIGNAL_PENDING_CALLS(tstate->interp);
+ int res = 0;
+
+ /* perform a bounded number of calls, in case of recursion */
+ struct _pending_calls *pending = &tstate->interp->ceval.pending;
+ for (int i=0; i<NPENDINGCALLS; i++) {
+ int (*func)(void *) = NULL;
+ void *arg = NULL;
+
+ /* pop one item off the queue while holding the lock */
+ PyThread_acquire_lock(pending->lock, WAIT_LOCK);
+ _pop_pending_call(pending, &func, &arg);
+ PyThread_release_lock(pending->lock);
+
+ /* having released the lock, perform the callback */
+ if (func == NULL) {
+ break;
+ }
+ res = func(arg);
+ if (res) {
+ goto error;
+ }
+ }
+
+ busy = 0;
+ return res;
+
+error:
+ busy = 0;
+ SIGNAL_PENDING_CALLS(tstate->interp);
+ return res;
+}
+
+void
+_Py_FinishPendingCalls(PyThreadState *tstate)
+{
+ assert(PyGILState_Check());
+
+ struct _pending_calls *pending = &tstate->interp->ceval.pending;
+
+ if (!_Py_atomic_load_relaxed(&(pending->calls_to_do))) {
+ return;
+ }
+
+ if (make_pending_calls(tstate) < 0) {
+ PyObject *exc, *val, *tb;
+ _PyErr_Fetch(tstate, &exc, &val, &tb);
+ PyErr_BadInternalCall();
+ _PyErr_ChainExceptions(exc, val, tb);
+ _PyErr_Print(tstate);
+ }
+}
+
+/* Py_MakePendingCalls() is a simple wrapper for the sake
+ of backward-compatibility. */
+int
+Py_MakePendingCalls(void)
+{
+ assert(PyGILState_Check());
+
+ PyThreadState *tstate = _PyThreadState_GET();
+
+ /* Python signal handler doesn't really queue a callback: it only signals
+ that a signal was received, see _PyEval_SignalReceived(). */
+ int res = handle_signals(tstate);
+ if (res != 0) {
+ return res;
+ }
+
+ res = make_pending_calls(tstate);
+ if (res != 0) {
+ return res;
+ }
+
+ return 0;
+}
+
+/* The interpreter's recursion limit */
+
+#ifndef Py_DEFAULT_RECURSION_LIMIT
+#define Py_DEFAULT_RECURSION_LIMIT 1000
+#endif
+
+int _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT;
+
+void
+_PyEval_InitRuntimeState(struct _ceval_runtime_state *ceval)
+{
+ _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT;
+ _gil_initialize(&ceval->gil);
+}
+
+int
+_PyEval_InitState(struct _ceval_state *ceval)
+{
+ ceval->recursion_limit = Py_DEFAULT_RECURSION_LIMIT;
+
+ struct _pending_calls *pending = &ceval->pending;
+ assert(pending->lock == NULL);
+
+ pending->lock = PyThread_allocate_lock();
+ if (pending->lock == NULL) {
+ return -1;
+ }
+
+ return 0;
+}
+
+void
+_PyEval_FiniState(struct _ceval_state *ceval)
+{
+ struct _pending_calls *pending = &ceval->pending;
+ if (pending->lock != NULL) {
+ PyThread_free_lock(pending->lock);
+ pending->lock = NULL;
+ }
+}
+
+int
+Py_GetRecursionLimit(void)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ return tstate->interp->ceval.recursion_limit;
+}
+
+void
+Py_SetRecursionLimit(int new_limit)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ tstate->interp->ceval.recursion_limit = new_limit;
+ if (_Py_IsMainInterpreter(tstate)) {
+ _Py_CheckRecursionLimit = new_limit;
+ }
+}
+
+/* The function _Py_EnterRecursiveCall() only calls _Py_CheckRecursiveCall()
+ if the recursion_depth reaches _Py_CheckRecursionLimit.
+ If USE_STACKCHECK, the macro decrements _Py_CheckRecursionLimit
+ to guarantee that _Py_CheckRecursiveCall() is regularly called.
+ Without USE_STACKCHECK, there is no need for this. */
+int
+_Py_CheckRecursiveCall(PyThreadState *tstate, const char *where)
+{
+ int recursion_limit = tstate->interp->ceval.recursion_limit;
+
+#ifdef USE_STACKCHECK
+ tstate->stackcheck_counter = 0;
+ if (PyOS_CheckStack()) {
+ --tstate->recursion_depth;
+ _PyErr_SetString(tstate, PyExc_MemoryError, "Stack overflow");
+ return -1;
+ }
+ if (_Py_IsMainInterpreter(tstate)) {
+ /* Needed for ABI backwards-compatibility (see bpo-31857) */
+ _Py_CheckRecursionLimit = recursion_limit;
+ }
+#endif
+ if (tstate->recursion_critical)
+ /* Somebody asked that we don't check for recursion. */
+ return 0;
+ if (tstate->overflowed) {
+ if (tstate->recursion_depth > recursion_limit + 50 || tstate->overflowed > 50) {
+ /* Overflowing while handling an overflow. Give up. */
+ Py_FatalError("Cannot recover from stack overflow.");
+ }
+ }
+ else {
+ if (tstate->recursion_depth > recursion_limit) {
+ tstate->overflowed++;
+ _PyErr_Format(tstate, PyExc_RecursionError,
+ "maximum recursion depth exceeded%s",
+ where);
+ tstate->overflowed--;
+ --tstate->recursion_depth;
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause);
+static int unpack_iterable(PyThreadState *, PyObject *, int, int, PyObject **);
+
+#define _Py_TracingPossible(ceval) ((ceval)->tracing_possible)
+
+
+PyObject *
+PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals)
+{
+ return PyEval_EvalCodeEx(co,
+ globals, locals,
+ (PyObject **)NULL, 0,
+ (PyObject **)NULL, 0,
+ (PyObject **)NULL, 0,
+ NULL, NULL);
+}
+
+
+/* Interpreter main loop */
+
+PyObject *
+PyEval_EvalFrame(PyFrameObject *f)
+{
+ /* Function kept for backward compatibility */
+ PyThreadState *tstate = _PyThreadState_GET();
+ return _PyEval_EvalFrame(tstate, f, 0);
+}
+
+PyObject *
+PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ return _PyEval_EvalFrame(tstate, f, throwflag);
+}
+
+
+/* Handle signals, pending calls, GIL drop request
+ and asynchronous exception */
+static int
+eval_frame_handle_pending(PyThreadState *tstate)
+{
+ _PyRuntimeState * const runtime = &_PyRuntime;
+ struct _ceval_runtime_state *ceval = &runtime->ceval;
+
+ /* Pending signals */
+ if (_Py_atomic_load_relaxed(&ceval->signals_pending)) {
+ if (handle_signals(tstate) != 0) {
+ return -1;
+ }
+ }
+
+ /* Pending calls */
+ struct _ceval_state *ceval2 = &tstate->interp->ceval;
+ if (_Py_atomic_load_relaxed(&ceval2->pending.calls_to_do)) {
+ if (make_pending_calls(tstate) != 0) {
+ return -1;
+ }
+ }
+
+ /* GIL drop request */
+ if (_Py_atomic_load_relaxed(&ceval2->gil_drop_request)) {
+ /* Give another thread a chance */
+ if (_PyThreadState_Swap(&runtime->gilstate, NULL) != tstate) {
+ Py_FatalError("tstate mix-up");
+ }
+ drop_gil(ceval, ceval2, tstate);
+
+ /* Other threads may run now */
+
+ take_gil(tstate);
+
+ if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) {
+ Py_FatalError("orphan tstate");
+ }
+ }
+
+ /* Check for asynchronous exception. */
+ if (tstate->async_exc != NULL) {
+ PyObject *exc = tstate->async_exc;
+ tstate->async_exc = NULL;
+ UNSIGNAL_ASYNC_EXC(tstate->interp);
+ _PyErr_SetNone(tstate, exc);
+ Py_DECREF(exc);
+ return -1;
+ }
+
+#ifdef MS_WINDOWS
+ // bpo-42296: On Windows, _PyEval_SignalReceived() can be called in a
+ // different thread than the Python thread, in which case
+ // _Py_ThreadCanHandleSignals() is wrong. Recompute eval_breaker in the
+ // current Python thread with the correct _Py_ThreadCanHandleSignals()
+ // value. It prevents to interrupt the eval loop at every instruction if
+ // the current Python thread cannot handle signals (if
+ // _Py_ThreadCanHandleSignals() is false).
+ COMPUTE_EVAL_BREAKER(tstate->interp, ceval, ceval2);
+#endif
+
+ return 0;
+}
+
+PyObject* _Py_HOT_FUNCTION
+_PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
+{
+ _Py_EnsureTstateNotNULL(tstate);
+
+#ifdef DXPAIRS
+ int lastopcode = 0;
+#endif
+ PyObject **stack_pointer; /* Next free slot in value stack */
+ const _Py_CODEUNIT *next_instr;
+ int opcode; /* Current opcode */
+ int oparg; /* Current opcode argument, if any */
+ PyObject **fastlocals, **freevars;
+ PyObject *retval = NULL; /* Return value */
+ struct _ceval_state * const ceval2 = &tstate->interp->ceval;
+ _Py_atomic_int * const eval_breaker = &ceval2->eval_breaker;
+ PyCodeObject *co;
+
+ /* when tracing we set things up so that
+
+ not (instr_lb <= current_bytecode_offset < instr_ub)
+
+ is true when the line being executed has changed. The
+ initial values are such as to make this false the first
+ time it is tested. */
+ int instr_ub = -1, instr_lb = 0, instr_prev = -1;
+
+ const _Py_CODEUNIT *first_instr;
+ PyObject *names;
+ PyObject *consts;
+ _PyOpcache *co_opcache;
+
+#ifdef LLTRACE
+ _Py_IDENTIFIER(__ltrace__);
+#endif
+
+/* Computed GOTOs, or
+ the-optimization-commonly-but-improperly-known-as-"threaded code"
+ using gcc's labels-as-values extension
+ (http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html).
+
+ The traditional bytecode evaluation loop uses a "switch" statement, which
+ decent compilers will optimize as a single indirect branch instruction
+ combined with a lookup table of jump addresses. However, since the
+ indirect jump instruction is shared by all opcodes, the CPU will have a
+ hard time making the right prediction for where to jump next (actually,
+ it will be always wrong except in the uncommon case of a sequence of
+ several identical opcodes).
+
+ "Threaded code" in contrast, uses an explicit jump table and an explicit
+ indirect jump instruction at the end of each opcode. Since the jump
+ instruction is at a different address for each opcode, the CPU will make a
+ separate prediction for each of these instructions, which is equivalent to
+ predicting the second opcode of each opcode pair. These predictions have
+ a much better chance to turn out valid, especially in small bytecode loops.
+
+ A mispredicted branch on a modern CPU flushes the whole pipeline and
+ can cost several CPU cycles (depending on the pipeline depth),
+ and potentially many more instructions (depending on the pipeline width).
+ A correctly predicted branch, however, is nearly free.
+
+ At the time of this writing, the "threaded code" version is up to 15-20%
+ faster than the normal "switch" version, depending on the compiler and the
+ CPU architecture.
+
+ We disable the optimization if DYNAMIC_EXECUTION_PROFILE is defined,
+ because it would render the measurements invalid.
+
+
+ NOTE: care must be taken that the compiler doesn't try to "optimize" the
+ indirect jumps by sharing them between all opcodes. Such optimizations
+ can be disabled on gcc by using the -fno-gcse flag (or possibly
+ -fno-crossjumping).
+*/
+
+#ifdef DYNAMIC_EXECUTION_PROFILE
+#undef USE_COMPUTED_GOTOS
+#define USE_COMPUTED_GOTOS 0
+#endif
+
+#ifdef HAVE_COMPUTED_GOTOS
+ #ifndef USE_COMPUTED_GOTOS
+ #define USE_COMPUTED_GOTOS 1
+ #endif
+#else
+ #if defined(USE_COMPUTED_GOTOS) && USE_COMPUTED_GOTOS
+ #error "Computed gotos are not supported on this compiler."
+ #endif
+ #undef USE_COMPUTED_GOTOS
+ #define USE_COMPUTED_GOTOS 0
+#endif
+
+#if USE_COMPUTED_GOTOS
+/* Import the static jump table */
+#include "opcode_targets.h"
+
+#define TARGET(op) \
+ op: \
+ TARGET_##op
+
+#ifdef LLTRACE
+#define FAST_DISPATCH() \
+ { \
+ if (!lltrace && !_Py_TracingPossible(ceval2) && !PyDTrace_LINE_ENABLED()) { \
+ f->f_lasti = INSTR_OFFSET(); \
+ NEXTOPARG(); \
+ goto *opcode_targets[opcode]; \
+ } \
+ goto fast_next_opcode; \
+ }
+#else
+#define FAST_DISPATCH() \
+ { \
+ if (!_Py_TracingPossible(ceval2) && !PyDTrace_LINE_ENABLED()) { \
+ f->f_lasti = INSTR_OFFSET(); \
+ NEXTOPARG(); \
+ goto *opcode_targets[opcode]; \
+ } \
+ goto fast_next_opcode; \
+ }
+#endif
+
+#define DISPATCH() \
+ { \
+ if (!_Py_atomic_load_relaxed(eval_breaker)) { \
+ FAST_DISPATCH(); \
+ } \
+ continue; \
+ }
+
+#else
+#define TARGET(op) op
+#define FAST_DISPATCH() goto fast_next_opcode
+#define DISPATCH() continue
+#endif
+
+
+/* Tuple access macros */
+
+#ifndef Py_DEBUG
+#define GETITEM(v, i) PyTuple_GET_ITEM((PyTupleObject *)(v), (i))
+#else
+#define GETITEM(v, i) PyTuple_GetItem((v), (i))
+#endif
+
+/* Code access macros */
+
+/* The integer overflow is checked by an assertion below. */
+#define INSTR_OFFSET() \
+ (sizeof(_Py_CODEUNIT) * (int)(next_instr - first_instr))
+#define NEXTOPARG() do { \
+ _Py_CODEUNIT word = *next_instr; \
+ opcode = _Py_OPCODE(word); \
+ oparg = _Py_OPARG(word); \
+ next_instr++; \
+ } while (0)
+#define JUMPTO(x) (next_instr = first_instr + (x) / sizeof(_Py_CODEUNIT))
+#define JUMPBY(x) (next_instr += (x) / sizeof(_Py_CODEUNIT))
+
+/* OpCode prediction macros
+ Some opcodes tend to come in pairs thus making it possible to
+ predict the second code when the first is run. For example,
+ COMPARE_OP is often followed by POP_JUMP_IF_FALSE or POP_JUMP_IF_TRUE.
+
+ Verifying the prediction costs a single high-speed test of a register
+ variable against a constant. If the pairing was good, then the
+ processor's own internal branch predication has a high likelihood of
+ success, resulting in a nearly zero-overhead transition to the
+ next opcode. A successful prediction saves a trip through the eval-loop
+ including its unpredictable switch-case branch. Combined with the
+ processor's internal branch prediction, a successful PREDICT has the
+ effect of making the two opcodes run as if they were a single new opcode
+ with the bodies combined.
+
+ If collecting opcode statistics, your choices are to either keep the
+ predictions turned-on and interpret the results as if some opcodes
+ had been combined or turn-off predictions so that the opcode frequency
+ counter updates for both opcodes.
+
+ Opcode prediction is disabled with threaded code, since the latter allows
+ the CPU to record separate branch prediction information for each
+ opcode.
+
+*/
+
+#define PREDICT_ID(op) PRED_##op
+
+#if defined(DYNAMIC_EXECUTION_PROFILE) || USE_COMPUTED_GOTOS
+#define PREDICT(op) if (0) goto PREDICT_ID(op)
+#else
+#define PREDICT(op) \
+ do { \
+ _Py_CODEUNIT word = *next_instr; \
+ opcode = _Py_OPCODE(word); \
+ if (opcode == op) { \
+ oparg = _Py_OPARG(word); \
+ next_instr++; \
+ goto PREDICT_ID(op); \
+ } \
+ } while(0)
+#endif
+#define PREDICTED(op) PREDICT_ID(op):
+
+
+/* Stack manipulation macros */
+
+/* The stack can grow at most MAXINT deep, as co_nlocals and
+ co_stacksize are ints. */
+#define STACK_LEVEL() ((int)(stack_pointer - f->f_valuestack))
+#define EMPTY() (STACK_LEVEL() == 0)
+#define TOP() (stack_pointer[-1])
+#define SECOND() (stack_pointer[-2])
+#define THIRD() (stack_pointer[-3])
+#define FOURTH() (stack_pointer[-4])
+#define PEEK(n) (stack_pointer[-(n)])
+#define SET_TOP(v) (stack_pointer[-1] = (v))
+#define SET_SECOND(v) (stack_pointer[-2] = (v))
+#define SET_THIRD(v) (stack_pointer[-3] = (v))
+#define SET_FOURTH(v) (stack_pointer[-4] = (v))
+#define SET_VALUE(n, v) (stack_pointer[-(n)] = (v))
+#define BASIC_STACKADJ(n) (stack_pointer += n)
+#define BASIC_PUSH(v) (*stack_pointer++ = (v))
+#define BASIC_POP() (*--stack_pointer)
+
+#ifdef LLTRACE
+#define PUSH(v) { (void)(BASIC_PUSH(v), \
+ lltrace && prtrace(tstate, TOP(), "push")); \
+ assert(STACK_LEVEL() <= co->co_stacksize); }
+#define POP() ((void)(lltrace && prtrace(tstate, TOP(), "pop")), \
+ BASIC_POP())
+#define STACK_GROW(n) do { \
+ assert(n >= 0); \
+ (void)(BASIC_STACKADJ(n), \
+ lltrace && prtrace(tstate, TOP(), "stackadj")); \
+ assert(STACK_LEVEL() <= co->co_stacksize); \
+ } while (0)
+#define STACK_SHRINK(n) do { \
+ assert(n >= 0); \
+ (void)(lltrace && prtrace(tstate, TOP(), "stackadj")); \
+ (void)(BASIC_STACKADJ(-n)); \
+ assert(STACK_LEVEL() <= co->co_stacksize); \
+ } while (0)
+#define EXT_POP(STACK_POINTER) ((void)(lltrace && \
+ prtrace(tstate, (STACK_POINTER)[-1], "ext_pop")), \
+ *--(STACK_POINTER))
+#else
+#define PUSH(v) BASIC_PUSH(v)
+#define POP() BASIC_POP()
+#define STACK_GROW(n) BASIC_STACKADJ(n)
+#define STACK_SHRINK(n) BASIC_STACKADJ(-n)
+#define EXT_POP(STACK_POINTER) (*--(STACK_POINTER))
+#endif
+
+/* Local variable macros */
+
+#define GETLOCAL(i) (fastlocals[i])
+
+/* The SETLOCAL() macro must not DECREF the local variable in-place and
+ then store the new value; it must copy the old value to a temporary
+ value, then store the new value, and then DECREF the temporary value.
+ This is because it is possible that during the DECREF the frame is
+ accessed by other code (e.g. a __del__ method or gc.collect()) and the
+ variable would be pointing to already-freed memory. */
+#define SETLOCAL(i, value) do { PyObject *tmp = GETLOCAL(i); \
+ GETLOCAL(i) = value; \
+ Py_XDECREF(tmp); } while (0)
+
+
+#define UNWIND_BLOCK(b) \
+ while (STACK_LEVEL() > (b)->b_level) { \
+ PyObject *v = POP(); \
+ Py_XDECREF(v); \
+ }
+
+#define UNWIND_EXCEPT_HANDLER(b) \
+ do { \
+ PyObject *type, *value, *traceback; \
+ _PyErr_StackItem *exc_info; \
+ assert(STACK_LEVEL() >= (b)->b_level + 3); \
+ while (STACK_LEVEL() > (b)->b_level + 3) { \
+ value = POP(); \
+ Py_XDECREF(value); \
+ } \
+ exc_info = tstate->exc_info; \
+ type = exc_info->exc_type; \
+ value = exc_info->exc_value; \
+ traceback = exc_info->exc_traceback; \
+ exc_info->exc_type = POP(); \
+ exc_info->exc_value = POP(); \
+ exc_info->exc_traceback = POP(); \
+ Py_XDECREF(type); \
+ Py_XDECREF(value); \
+ Py_XDECREF(traceback); \
+ } while(0)
+
+ /* macros for opcode cache */
+#define OPCACHE_CHECK() \
+ do { \
+ co_opcache = NULL; \
+ if (co->co_opcache != NULL) { \
+ unsigned char co_opt_offset = \
+ co->co_opcache_map[next_instr - first_instr]; \
+ if (co_opt_offset > 0) { \
+ assert(co_opt_offset <= co->co_opcache_size); \
+ co_opcache = &co->co_opcache[co_opt_offset - 1]; \
+ assert(co_opcache != NULL); \
+ } \
+ } \
+ } while (0)
+
+#if OPCACHE_STATS
+
+#define OPCACHE_STAT_GLOBAL_HIT() \
+ do { \
+ if (co->co_opcache != NULL) opcache_global_hits++; \
+ } while (0)
+
+#define OPCACHE_STAT_GLOBAL_MISS() \
+ do { \
+ if (co->co_opcache != NULL) opcache_global_misses++; \
+ } while (0)
+
+#define OPCACHE_STAT_GLOBAL_OPT() \
+ do { \
+ if (co->co_opcache != NULL) opcache_global_opts++; \
+ } while (0)
+
+#else /* OPCACHE_STATS */
+
+#define OPCACHE_STAT_GLOBAL_HIT()
+#define OPCACHE_STAT_GLOBAL_MISS()
+#define OPCACHE_STAT_GLOBAL_OPT()
+
+#endif
+
+/* Start of code */
+
+ /* push frame */
+ if (_Py_EnterRecursiveCall(tstate, "")) {
+ return NULL;
+ }
+
+ tstate->frame = f;
+
+ if (tstate->use_tracing) {
+ if (tstate->c_tracefunc != NULL) {
+ /* tstate->c_tracefunc, if defined, is a
+ function that will be called on *every* entry
+ to a code block. Its return value, if not
+ None, is a function that will be called at
+ the start of each executed line of code.
+ (Actually, the function must return itself
+ in order to continue tracing.) The trace
+ functions are called with three arguments:
+ a pointer to the current frame, a string
+ indicating why the function is called, and
+ an argument which depends on the situation.
+ The global trace function is also called
+ whenever an exception is detected. */
+ if (call_trace_protected(tstate->c_tracefunc,
+ tstate->c_traceobj,
+ tstate, f, PyTrace_CALL, Py_None)) {
+ /* Trace function raised an error */
+ goto exit_eval_frame;
+ }
+ }
+ if (tstate->c_profilefunc != NULL) {
+ /* Similar for c_profilefunc, except it needn't
+ return itself and isn't called for "line" events */
+ if (call_trace_protected(tstate->c_profilefunc,
+ tstate->c_profileobj,
+ tstate, f, PyTrace_CALL, Py_None)) {
+ /* Profile function raised an error */
+ goto exit_eval_frame;
+ }
+ }
+ }
+
+ if (PyDTrace_FUNCTION_ENTRY_ENABLED())
+ dtrace_function_entry(f);
+
+ co = f->f_code;
+ names = co->co_names;
+ consts = co->co_consts;
+ fastlocals = f->f_localsplus;
+ freevars = f->f_localsplus + co->co_nlocals;
+ assert(PyBytes_Check(co->co_code));
+ assert(PyBytes_GET_SIZE(co->co_code) <= INT_MAX);
+ assert(PyBytes_GET_SIZE(co->co_code) % sizeof(_Py_CODEUNIT) == 0);
+ assert(_Py_IS_ALIGNED(PyBytes_AS_STRING(co->co_code), sizeof(_Py_CODEUNIT)));
+ first_instr = (_Py_CODEUNIT *) PyBytes_AS_STRING(co->co_code);
+ /*
+ f->f_lasti refers to the index of the last instruction,
+ unless it's -1 in which case next_instr should be first_instr.
+
+ YIELD_FROM sets f_lasti to itself, in order to repeatedly yield
+ multiple values.
+
+ When the PREDICT() macros are enabled, some opcode pairs follow in
+ direct succession without updating f->f_lasti. A successful
+ prediction effectively links the two codes together as if they
+ were a single new opcode; accordingly,f->f_lasti will point to
+ the first code in the pair (for instance, GET_ITER followed by
+ FOR_ITER is effectively a single opcode and f->f_lasti will point
+ to the beginning of the combined pair.)
+ */
+ assert(f->f_lasti >= -1);
+ next_instr = first_instr;
+ if (f->f_lasti >= 0) {
+ assert(f->f_lasti % sizeof(_Py_CODEUNIT) == 0);
+ next_instr += f->f_lasti / sizeof(_Py_CODEUNIT) + 1;
+ }
+ stack_pointer = f->f_stacktop;
+ assert(stack_pointer != NULL);
+ f->f_stacktop = NULL; /* remains NULL unless yield suspends frame */
+ f->f_executing = 1;
+
+ if (co->co_opcache_flag < OPCACHE_MIN_RUNS) {
+ co->co_opcache_flag++;
+ if (co->co_opcache_flag == OPCACHE_MIN_RUNS) {
+ if (_PyCode_InitOpcache(co) < 0) {
+ goto exit_eval_frame;
+ }
+#if OPCACHE_STATS
+ opcache_code_objects_extra_mem +=
+ PyBytes_Size(co->co_code) / sizeof(_Py_CODEUNIT) +
+ sizeof(_PyOpcache) * co->co_opcache_size;
+ opcache_code_objects++;
+#endif
+ }
+ }
+
+#ifdef LLTRACE
+ lltrace = _PyDict_GetItemId(f->f_globals, &PyId___ltrace__) != NULL;
+#endif
+
+ if (throwflag) /* support for generator.throw() */
+ goto error;
+
+#ifdef Py_DEBUG
+ /* _PyEval_EvalFrameDefault() must not be called with an exception set,
+ because it can clear it (directly or indirectly) and so the
+ caller loses its exception */
+ assert(!_PyErr_Occurred(tstate));
+#endif
+
+main_loop:
+ for (;;) {
+ assert(stack_pointer >= f->f_valuestack); /* else underflow */
+ assert(STACK_LEVEL() <= co->co_stacksize); /* else overflow */
+ assert(!_PyErr_Occurred(tstate));
+
+ /* Do periodic things. Doing this every time through
+ the loop would add too much overhead, so we do it
+ only every Nth instruction. We also do it if
+ ``pending.calls_to_do'' is set, i.e. when an asynchronous
+ event needs attention (e.g. a signal handler or
+ async I/O handler); see Py_AddPendingCall() and
+ Py_MakePendingCalls() above. */
+
+ if (_Py_atomic_load_relaxed(eval_breaker)) {
+ opcode = _Py_OPCODE(*next_instr);
+ if (opcode == SETUP_FINALLY ||
+ opcode == SETUP_WITH ||
+ opcode == BEFORE_ASYNC_WITH ||
+ opcode == YIELD_FROM) {
+ /* Few cases where we skip running signal handlers and other
+ pending calls:
+ - If we're about to enter the 'with:'. It will prevent
+ emitting a resource warning in the common idiom
+ 'with open(path) as file:'.
+ - If we're about to enter the 'async with:'.
+ - If we're about to enter the 'try:' of a try/finally (not
+ *very* useful, but might help in some cases and it's
+ traditional)
+ - If we're resuming a chain of nested 'yield from' or
+ 'await' calls, then each frame is parked with YIELD_FROM
+ as its next opcode. If the user hit control-C we want to
+ wait until we've reached the innermost frame before
+ running the signal handler and raising KeyboardInterrupt
+ (see bpo-30039).
+ */
+ goto fast_next_opcode;
+ }
+
+ if (eval_frame_handle_pending(tstate) != 0) {
+ goto error;
+ }
+ }
+
+ fast_next_opcode:
+ f->f_lasti = INSTR_OFFSET();
+
+ if (PyDTrace_LINE_ENABLED())
+ maybe_dtrace_line(f, &instr_lb, &instr_ub, &instr_prev);
+
+ /* line-by-line tracing support */
+
+ if (_Py_TracingPossible(ceval2) &&
+ tstate->c_tracefunc != NULL && !tstate->tracing) {
+ int err;
+ /* see maybe_call_line_trace
+ for expository comments */
+ f->f_stacktop = stack_pointer;
+
+ err = maybe_call_line_trace(tstate->c_tracefunc,
+ tstate->c_traceobj,
+ tstate, f,
+ &instr_lb, &instr_ub, &instr_prev);
+ /* Reload possibly changed frame fields */
+ JUMPTO(f->f_lasti);
+ if (f->f_stacktop != NULL) {
+ stack_pointer = f->f_stacktop;
+ f->f_stacktop = NULL;
+ }
+ if (err)
+ /* trace function raised an exception */
+ goto error;
+ }
+
+ /* Extract opcode and argument */
+
+ NEXTOPARG();
+ dispatch_opcode:
+#ifdef DYNAMIC_EXECUTION_PROFILE
+#ifdef DXPAIRS
+ dxpairs[lastopcode][opcode]++;
+ lastopcode = opcode;
+#endif
+ dxp[opcode]++;
+#endif
+
+#ifdef LLTRACE
+ /* Instruction tracing */
+
+ if (lltrace) {
+ if (HAS_ARG(opcode)) {
+ printf("%d: %d, %d\n",
+ f->f_lasti, opcode, oparg);
+ }
+ else {
+ printf("%d: %d\n",
+ f->f_lasti, opcode);
+ }
+ }
+#endif
+
+ switch (opcode) {
+
+ /* BEWARE!
+ It is essential that any operation that fails must goto error
+ and that all operation that succeed call [FAST_]DISPATCH() ! */
+
+ case TARGET(NOP): {
+ FAST_DISPATCH();
+ }
+
+ case TARGET(LOAD_FAST): {
+ PyObject *value = GETLOCAL(oparg);
+ if (value == NULL) {
+ format_exc_check_arg(tstate, PyExc_UnboundLocalError,
+ UNBOUNDLOCAL_ERROR_MSG,
+ PyTuple_GetItem(co->co_varnames, oparg));
+ goto error;
+ }
+ Py_INCREF(value);
+ PUSH(value);
+ FAST_DISPATCH();
+ }
+
+ case TARGET(LOAD_CONST): {
+ PREDICTED(LOAD_CONST);
+ PyObject *value = GETITEM(consts, oparg);
+ Py_INCREF(value);
+ PUSH(value);
+ FAST_DISPATCH();
+ }
+
+ case TARGET(STORE_FAST): {
+ PREDICTED(STORE_FAST);
+ PyObject *value = POP();
+ SETLOCAL(oparg, value);
+ FAST_DISPATCH();
+ }
+
+ case TARGET(POP_TOP): {
+ PyObject *value = POP();
+ Py_DECREF(value);
+ FAST_DISPATCH();
+ }
+
+ case TARGET(ROT_TWO): {
+ PyObject *top = TOP();
+ PyObject *second = SECOND();
+ SET_TOP(second);
+ SET_SECOND(top);
+ FAST_DISPATCH();
+ }
+
+ case TARGET(ROT_THREE): {
+ PyObject *top = TOP();
+ PyObject *second = SECOND();
+ PyObject *third = THIRD();
+ SET_TOP(second);
+ SET_SECOND(third);
+ SET_THIRD(top);
+ FAST_DISPATCH();
+ }
+
+ case TARGET(ROT_FOUR): {
+ PyObject *top = TOP();
+ PyObject *second = SECOND();
+ PyObject *third = THIRD();
+ PyObject *fourth = FOURTH();
+ SET_TOP(second);
+ SET_SECOND(third);
+ SET_THIRD(fourth);
+ SET_FOURTH(top);
+ FAST_DISPATCH();
+ }
+
+ case TARGET(DUP_TOP): {
+ PyObject *top = TOP();
+ Py_INCREF(top);
+ PUSH(top);
+ FAST_DISPATCH();
+ }
+
+ case TARGET(DUP_TOP_TWO): {
+ PyObject *top = TOP();
+ PyObject *second = SECOND();
+ Py_INCREF(top);
+ Py_INCREF(second);
+ STACK_GROW(2);
+ SET_TOP(top);
+ SET_SECOND(second);
+ FAST_DISPATCH();
+ }
+
+ case TARGET(UNARY_POSITIVE): {
+ PyObject *value = TOP();
+ PyObject *res = PyNumber_Positive(value);
+ Py_DECREF(value);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(UNARY_NEGATIVE): {
+ PyObject *value = TOP();
+ PyObject *res = PyNumber_Negative(value);
+ Py_DECREF(value);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(UNARY_NOT): {
+ PyObject *value = TOP();
+ int err = PyObject_IsTrue(value);
+ Py_DECREF(value);
+ if (err == 0) {
+ Py_INCREF(Py_True);
+ SET_TOP(Py_True);
+ DISPATCH();
+ }
+ else if (err > 0) {
+ Py_INCREF(Py_False);
+ SET_TOP(Py_False);
+ DISPATCH();
+ }
+ STACK_SHRINK(1);
+ goto error;
+ }
+
+ case TARGET(UNARY_INVERT): {
+ PyObject *value = TOP();
+ PyObject *res = PyNumber_Invert(value);
+ Py_DECREF(value);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(BINARY_POWER): {
+ PyObject *exp = POP();
+ PyObject *base = TOP();
+ PyObject *res = PyNumber_Power(base, exp, Py_None);
+ Py_DECREF(base);
+ Py_DECREF(exp);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(BINARY_MULTIPLY): {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_Multiply(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(BINARY_MATRIX_MULTIPLY): {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_MatrixMultiply(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(BINARY_TRUE_DIVIDE): {
+ PyObject *divisor = POP();
+ PyObject *dividend = TOP();
+ PyObject *quotient = PyNumber_TrueDivide(dividend, divisor);
+ Py_DECREF(dividend);
+ Py_DECREF(divisor);
+ SET_TOP(quotient);
+ if (quotient == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(BINARY_FLOOR_DIVIDE): {
+ PyObject *divisor = POP();
+ PyObject *dividend = TOP();
+ PyObject *quotient = PyNumber_FloorDivide(dividend, divisor);
+ Py_DECREF(dividend);
+ Py_DECREF(divisor);
+ SET_TOP(quotient);
+ if (quotient == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(BINARY_MODULO): {
+ PyObject *divisor = POP();
+ PyObject *dividend = TOP();
+ PyObject *res;
+ if (PyUnicode_CheckExact(dividend) && (
+ !PyUnicode_Check(divisor) || PyUnicode_CheckExact(divisor))) {
+ // fast path; string formatting, but not if the RHS is a str subclass
+ // (see issue28598)
+ res = PyUnicode_Format(dividend, divisor);
+ } else {
+ res = PyNumber_Remainder(dividend, divisor);
+ }
+ Py_DECREF(divisor);
+ Py_DECREF(dividend);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(BINARY_ADD): {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *sum;
+ /* NOTE(haypo): Please don't try to micro-optimize int+int on
+ CPython using bytecode, it is simply worthless.
+ See http://bugs.python.org/issue21955 and
+ http://bugs.python.org/issue10044 for the discussion. In short,
+ no patch shown any impact on a realistic benchmark, only a minor
+ speedup on microbenchmarks. */
+ if (PyUnicode_CheckExact(left) &&
+ PyUnicode_CheckExact(right)) {
+ sum = unicode_concatenate(tstate, left, right, f, next_instr);
+ /* unicode_concatenate consumed the ref to left */
+ }
+ else {
+ sum = PyNumber_Add(left, right);
+ Py_DECREF(left);
+ }
+ Py_DECREF(right);
+ SET_TOP(sum);
+ if (sum == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(BINARY_SUBTRACT): {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *diff = PyNumber_Subtract(left, right);
+ Py_DECREF(right);
+ Py_DECREF(left);
+ SET_TOP(diff);
+ if (diff == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(BINARY_SUBSCR): {
+ PyObject *sub = POP();
+ PyObject *container = TOP();
+ PyObject *res = PyObject_GetItem(container, sub);
+ Py_DECREF(container);
+ Py_DECREF(sub);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(BINARY_LSHIFT): {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_Lshift(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(BINARY_RSHIFT): {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_Rshift(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(BINARY_AND): {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_And(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(BINARY_XOR): {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_Xor(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(BINARY_OR): {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_Or(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(LIST_APPEND): {
+ PyObject *v = POP();
+ PyObject *list = PEEK(oparg);
+ int err;
+ err = PyList_Append(list, v);
+ Py_DECREF(v);
+ if (err != 0)
+ goto error;
+ PREDICT(JUMP_ABSOLUTE);
+ DISPATCH();
+ }
+
+ case TARGET(SET_ADD): {
+ PyObject *v = POP();
+ PyObject *set = PEEK(oparg);
+ int err;
+ err = PySet_Add(set, v);
+ Py_DECREF(v);
+ if (err != 0)
+ goto error;
+ PREDICT(JUMP_ABSOLUTE);
+ DISPATCH();
+ }
+
+ case TARGET(INPLACE_POWER): {
+ PyObject *exp = POP();
+ PyObject *base = TOP();
+ PyObject *res = PyNumber_InPlacePower(base, exp, Py_None);
+ Py_DECREF(base);
+ Py_DECREF(exp);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(INPLACE_MULTIPLY): {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_InPlaceMultiply(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(INPLACE_MATRIX_MULTIPLY): {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_InPlaceMatrixMultiply(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(INPLACE_TRUE_DIVIDE): {
+ PyObject *divisor = POP();
+ PyObject *dividend = TOP();
+ PyObject *quotient = PyNumber_InPlaceTrueDivide(dividend, divisor);
+ Py_DECREF(dividend);
+ Py_DECREF(divisor);
+ SET_TOP(quotient);
+ if (quotient == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(INPLACE_FLOOR_DIVIDE): {
+ PyObject *divisor = POP();
+ PyObject *dividend = TOP();
+ PyObject *quotient = PyNumber_InPlaceFloorDivide(dividend, divisor);
+ Py_DECREF(dividend);
+ Py_DECREF(divisor);
+ SET_TOP(quotient);
+ if (quotient == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(INPLACE_MODULO): {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *mod = PyNumber_InPlaceRemainder(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(mod);
+ if (mod == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(INPLACE_ADD): {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *sum;
+ if (PyUnicode_CheckExact(left) && PyUnicode_CheckExact(right)) {
+ sum = unicode_concatenate(tstate, left, right, f, next_instr);
+ /* unicode_concatenate consumed the ref to left */
+ }
+ else {
+ sum = PyNumber_InPlaceAdd(left, right);
+ Py_DECREF(left);
+ }
+ Py_DECREF(right);
+ SET_TOP(sum);
+ if (sum == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(INPLACE_SUBTRACT): {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *diff = PyNumber_InPlaceSubtract(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(diff);
+ if (diff == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(INPLACE_LSHIFT): {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_InPlaceLshift(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(INPLACE_RSHIFT): {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_InPlaceRshift(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(INPLACE_AND): {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_InPlaceAnd(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(INPLACE_XOR): {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_InPlaceXor(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(INPLACE_OR): {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_InPlaceOr(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(STORE_SUBSCR): {
+ PyObject *sub = TOP();
+ PyObject *container = SECOND();
+ PyObject *v = THIRD();
+ int err;
+ STACK_SHRINK(3);
+ /* container[sub] = v */
+ err = PyObject_SetItem(container, sub, v);
+ Py_DECREF(v);
+ Py_DECREF(container);
+ Py_DECREF(sub);
+ if (err != 0)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(DELETE_SUBSCR): {
+ PyObject *sub = TOP();
+ PyObject *container = SECOND();
+ int err;
+ STACK_SHRINK(2);
+ /* del container[sub] */
+ err = PyObject_DelItem(container, sub);
+ Py_DECREF(container);
+ Py_DECREF(sub);
+ if (err != 0)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(PRINT_EXPR): {
+ _Py_IDENTIFIER(displayhook);
+ PyObject *value = POP();
+ PyObject *hook = _PySys_GetObjectId(&PyId_displayhook);
+ PyObject *res;
+ if (hook == NULL) {
+ _PyErr_SetString(tstate, PyExc_RuntimeError,
+ "lost sys.displayhook");
+ Py_DECREF(value);
+ goto error;
+ }
+ res = PyObject_CallOneArg(hook, value);
+ Py_DECREF(value);
+ if (res == NULL)
+ goto error;
+ Py_DECREF(res);
+ DISPATCH();
+ }
+
+ case TARGET(RAISE_VARARGS): {
+ PyObject *cause = NULL, *exc = NULL;
+ switch (oparg) {
+ case 2:
+ cause = POP(); /* cause */
+ /* fall through */
+ case 1:
+ exc = POP(); /* exc */
+ /* fall through */
+ case 0:
+ if (do_raise(tstate, exc, cause)) {
+ goto exception_unwind;
+ }
+ break;
+ default:
+ _PyErr_SetString(tstate, PyExc_SystemError,
+ "bad RAISE_VARARGS oparg");
+ break;
+ }
+ goto error;
+ }
+
+ case TARGET(RETURN_VALUE): {
+ retval = POP();
+ assert(f->f_iblock == 0);
+ assert(EMPTY());
+ goto exiting;
+ }
+
+ case TARGET(GET_AITER): {
+ unaryfunc getter = NULL;
+ PyObject *iter = NULL;
+ PyObject *obj = TOP();
+ PyTypeObject *type = Py_TYPE(obj);
+
+ if (type->tp_as_async != NULL) {
+ getter = type->tp_as_async->am_aiter;
+ }
+
+ if (getter != NULL) {
+ iter = (*getter)(obj);
+ Py_DECREF(obj);
+ if (iter == NULL) {
+ SET_TOP(NULL);
+ goto error;
+ }
+ }
+ else {
+ SET_TOP(NULL);
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "'async for' requires an object with "
+ "__aiter__ method, got %.100s",
+ type->tp_name);
+ Py_DECREF(obj);
+ goto error;
+ }
+
+ if (Py_TYPE(iter)->tp_as_async == NULL ||
+ Py_TYPE(iter)->tp_as_async->am_anext == NULL) {
+
+ SET_TOP(NULL);
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "'async for' received an object from __aiter__ "
+ "that does not implement __anext__: %.100s",
+ Py_TYPE(iter)->tp_name);
+ Py_DECREF(iter);
+ goto error;
+ }
+
+ SET_TOP(iter);
+ DISPATCH();
+ }
+
+ case TARGET(GET_ANEXT): {
+ unaryfunc getter = NULL;
+ PyObject *next_iter = NULL;
+ PyObject *awaitable = NULL;
+ PyObject *aiter = TOP();
+ PyTypeObject *type = Py_TYPE(aiter);
+
+ if (PyAsyncGen_CheckExact(aiter)) {
+ awaitable = type->tp_as_async->am_anext(aiter);
+ if (awaitable == NULL) {
+ goto error;
+ }
+ } else {
+ if (type->tp_as_async != NULL){
+ getter = type->tp_as_async->am_anext;
+ }
+
+ if (getter != NULL) {
+ next_iter = (*getter)(aiter);
+ if (next_iter == NULL) {
+ goto error;
+ }
+ }
+ else {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "'async for' requires an iterator with "
+ "__anext__ method, got %.100s",
+ type->tp_name);
+ goto error;
+ }
+
+ awaitable = _PyCoro_GetAwaitableIter(next_iter);
+ if (awaitable == NULL) {
+ _PyErr_FormatFromCause(
+ PyExc_TypeError,
+ "'async for' received an invalid object "
+ "from __anext__: %.100s",
+ Py_TYPE(next_iter)->tp_name);
+
+ Py_DECREF(next_iter);
+ goto error;
+ } else {
+ Py_DECREF(next_iter);
+ }
+ }
+
+ PUSH(awaitable);
+ PREDICT(LOAD_CONST);
+ DISPATCH();
+ }
+
+ case TARGET(GET_AWAITABLE): {
+ PREDICTED(GET_AWAITABLE);
+ PyObject *iterable = TOP();
+ PyObject *iter = _PyCoro_GetAwaitableIter(iterable);
+
+ if (iter == NULL) {
+ int opcode_at_minus_3 = 0;
+ if ((next_instr - first_instr) > 2) {
+ opcode_at_minus_3 = _Py_OPCODE(next_instr[-3]);
+ }
+ format_awaitable_error(tstate, Py_TYPE(iterable),
+ opcode_at_minus_3,
+ _Py_OPCODE(next_instr[-2]));
+ }
+
+ Py_DECREF(iterable);
+
+ if (iter != NULL && PyCoro_CheckExact(iter)) {
+ PyObject *yf = _PyGen_yf((PyGenObject*)iter);
+ if (yf != NULL) {
+ /* `iter` is a coroutine object that is being
+ awaited, `yf` is a pointer to the current awaitable
+ being awaited on. */
+ Py_DECREF(yf);
+ Py_CLEAR(iter);
+ _PyErr_SetString(tstate, PyExc_RuntimeError,
+ "coroutine is being awaited already");
+ /* The code below jumps to `error` if `iter` is NULL. */
+ }
+ }
+
+ SET_TOP(iter); /* Even if it's NULL */
+
+ if (iter == NULL) {
+ goto error;
+ }
+
+ PREDICT(LOAD_CONST);
+ DISPATCH();
+ }
+
+ case TARGET(YIELD_FROM): {
+ PyObject *v = POP();
+ PyObject *receiver = TOP();
+ int err;
+ if (PyGen_CheckExact(receiver) || PyCoro_CheckExact(receiver)) {
+ retval = _PyGen_Send((PyGenObject *)receiver, v);
+ } else {
+ _Py_IDENTIFIER(send);
+ if (v == Py_None)
+ retval = Py_TYPE(receiver)->tp_iternext(receiver);
+ else
+ retval = _PyObject_CallMethodIdOneArg(receiver, &PyId_send, v);
+ }
+ Py_DECREF(v);
+ if (retval == NULL) {
+ PyObject *val;
+ if (tstate->c_tracefunc != NULL
+ && _PyErr_ExceptionMatches(tstate, PyExc_StopIteration))
+ call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f);
+ err = _PyGen_FetchStopIterationValue(&val);
+ if (err < 0)
+ goto error;
+ Py_DECREF(receiver);
+ SET_TOP(val);
+ DISPATCH();
+ }
+ /* receiver remains on stack, retval is value to be yielded */
+ f->f_stacktop = stack_pointer;
+ /* and repeat... */
+ assert(f->f_lasti >= (int)sizeof(_Py_CODEUNIT));
+ f->f_lasti -= sizeof(_Py_CODEUNIT);
+ goto exiting;
+ }
+
+ case TARGET(YIELD_VALUE): {
+ retval = POP();
+
+ if (co->co_flags & CO_ASYNC_GENERATOR) {
+ PyObject *w = _PyAsyncGenValueWrapperNew(retval);
+ Py_DECREF(retval);
+ if (w == NULL) {
+ retval = NULL;
+ goto error;
+ }
+ retval = w;
+ }
+
+ f->f_stacktop = stack_pointer;
+ goto exiting;
+ }
+
+ case TARGET(POP_EXCEPT): {
+ PyObject *type, *value, *traceback;
+ _PyErr_StackItem *exc_info;
+ PyTryBlock *b = PyFrame_BlockPop(f);
+ if (b->b_type != EXCEPT_HANDLER) {
+ _PyErr_SetString(tstate, PyExc_SystemError,
+ "popped block is not an except handler");
+ goto error;
+ }
+ assert(STACK_LEVEL() >= (b)->b_level + 3 &&
+ STACK_LEVEL() <= (b)->b_level + 4);
+ exc_info = tstate->exc_info;
+ type = exc_info->exc_type;
+ value = exc_info->exc_value;
+ traceback = exc_info->exc_traceback;
+ exc_info->exc_type = POP();
+ exc_info->exc_value = POP();
+ exc_info->exc_traceback = POP();
+ Py_XDECREF(type);
+ Py_XDECREF(value);
+ Py_XDECREF(traceback);
+ DISPATCH();
+ }
+
+ case TARGET(POP_BLOCK): {
+ PREDICTED(POP_BLOCK);
+ PyFrame_BlockPop(f);
+ DISPATCH();
+ }
+
+ case TARGET(RERAISE): {
+ PyObject *exc = POP();
+ PyObject *val = POP();
+ PyObject *tb = POP();
+ assert(PyExceptionClass_Check(exc));
+ _PyErr_Restore(tstate, exc, val, tb);
+ goto exception_unwind;
+ }
+
+ case TARGET(END_ASYNC_FOR): {
+ PyObject *exc = POP();
+ assert(PyExceptionClass_Check(exc));
+ if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) {
+ PyTryBlock *b = PyFrame_BlockPop(f);
+ assert(b->b_type == EXCEPT_HANDLER);
+ Py_DECREF(exc);
+ UNWIND_EXCEPT_HANDLER(b);
+ Py_DECREF(POP());
+ JUMPBY(oparg);
+ FAST_DISPATCH();
+ }
+ else {
+ PyObject *val = POP();
+ PyObject *tb = POP();
+ _PyErr_Restore(tstate, exc, val, tb);
+ goto exception_unwind;
+ }
+ }
+
+ case TARGET(LOAD_ASSERTION_ERROR): {
+ PyObject *value = PyExc_AssertionError;
+ Py_INCREF(value);
+ PUSH(value);
+ FAST_DISPATCH();
+ }
+
+ case TARGET(LOAD_BUILD_CLASS): {
+ _Py_IDENTIFIER(__build_class__);
+
+ PyObject *bc;
+ if (PyDict_CheckExact(f->f_builtins)) {
+ bc = _PyDict_GetItemIdWithError(f->f_builtins, &PyId___build_class__);
+ if (bc == NULL) {
+ if (!_PyErr_Occurred(tstate)) {
+ _PyErr_SetString(tstate, PyExc_NameError,
+ "__build_class__ not found");
+ }
+ goto error;
+ }
+ Py_INCREF(bc);
+ }
+ else {
+ PyObject *build_class_str = _PyUnicode_FromId(&PyId___build_class__);
+ if (build_class_str == NULL)
+ goto error;
+ bc = PyObject_GetItem(f->f_builtins, build_class_str);
+ if (bc == NULL) {
+ if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError))
+ _PyErr_SetString(tstate, PyExc_NameError,
+ "__build_class__ not found");
+ goto error;
+ }
+ }
+ PUSH(bc);
+ DISPATCH();
+ }
+
+ case TARGET(STORE_NAME): {
+ PyObject *name = GETITEM(names, oparg);
+ PyObject *v = POP();
+ PyObject *ns = f->f_locals;
+ int err;
+ if (ns == NULL) {
+ _PyErr_Format(tstate, PyExc_SystemError,
+ "no locals found when storing %R", name);
+ Py_DECREF(v);
+ goto error;
+ }
+ if (PyDict_CheckExact(ns))
+ err = PyDict_SetItem(ns, name, v);
+ else
+ err = PyObject_SetItem(ns, name, v);
+ Py_DECREF(v);
+ if (err != 0)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(DELETE_NAME): {
+ PyObject *name = GETITEM(names, oparg);
+ PyObject *ns = f->f_locals;
+ int err;
+ if (ns == NULL) {
+ _PyErr_Format(tstate, PyExc_SystemError,
+ "no locals when deleting %R", name);
+ goto error;
+ }
+ err = PyObject_DelItem(ns, name);
+ if (err != 0) {
+ format_exc_check_arg(tstate, PyExc_NameError,
+ NAME_ERROR_MSG,
+ name);
+ goto error;
+ }
+ DISPATCH();
+ }
+
+ case TARGET(UNPACK_SEQUENCE): {
+ PREDICTED(UNPACK_SEQUENCE);
+ PyObject *seq = POP(), *item, **items;
+ if (PyTuple_CheckExact(seq) &&
+ PyTuple_GET_SIZE(seq) == oparg) {
+ items = ((PyTupleObject *)seq)->ob_item;
+ while (oparg--) {
+ item = items[oparg];
+ Py_INCREF(item);
+ PUSH(item);
+ }
+ } else if (PyList_CheckExact(seq) &&
+ PyList_GET_SIZE(seq) == oparg) {
+ items = ((PyListObject *)seq)->ob_item;
+ while (oparg--) {
+ item = items[oparg];
+ Py_INCREF(item);
+ PUSH(item);
+ }
+ } else if (unpack_iterable(tstate, seq, oparg, -1,
+ stack_pointer + oparg)) {
+ STACK_GROW(oparg);
+ } else {
+ /* unpack_iterable() raised an exception */
+ Py_DECREF(seq);
+ goto error;
+ }
+ Py_DECREF(seq);
+ DISPATCH();
+ }
+
+ case TARGET(UNPACK_EX): {
+ int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8);
+ PyObject *seq = POP();
+
+ if (unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8,
+ stack_pointer + totalargs)) {
+ stack_pointer += totalargs;
+ } else {
+ Py_DECREF(seq);
+ goto error;
+ }
+ Py_DECREF(seq);
+ DISPATCH();
+ }
+
+ case TARGET(STORE_ATTR): {
+ PyObject *name = GETITEM(names, oparg);
+ PyObject *owner = TOP();
+ PyObject *v = SECOND();
+ int err;
+ STACK_SHRINK(2);
+ err = PyObject_SetAttr(owner, name, v);
+ Py_DECREF(v);
+ Py_DECREF(owner);
+ if (err != 0)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(DELETE_ATTR): {
+ PyObject *name = GETITEM(names, oparg);
+ PyObject *owner = POP();
+ int err;
+ err = PyObject_SetAttr(owner, name, (PyObject *)NULL);
+ Py_DECREF(owner);
+ if (err != 0)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(STORE_GLOBAL): {
+ PyObject *name = GETITEM(names, oparg);
+ PyObject *v = POP();
+ int err;
+ err = PyDict_SetItem(f->f_globals, name, v);
+ Py_DECREF(v);
+ if (err != 0)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(DELETE_GLOBAL): {
+ PyObject *name = GETITEM(names, oparg);
+ int err;
+ err = PyDict_DelItem(f->f_globals, name);
+ if (err != 0) {
+ if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
+ format_exc_check_arg(tstate, PyExc_NameError,
+ NAME_ERROR_MSG, name);
+ }
+ goto error;
+ }
+ DISPATCH();
+ }
+
+ case TARGET(LOAD_NAME): {
+ PyObject *name = GETITEM(names, oparg);
+ PyObject *locals = f->f_locals;
+ PyObject *v;
+ if (locals == NULL) {
+ _PyErr_Format(tstate, PyExc_SystemError,
+ "no locals when loading %R", name);
+ goto error;
+ }
+ if (PyDict_CheckExact(locals)) {
+ v = PyDict_GetItemWithError(locals, name);
+ if (v != NULL) {
+ Py_INCREF(v);
+ }
+ else if (_PyErr_Occurred(tstate)) {
+ goto error;
+ }
+ }
+ else {
+ v = PyObject_GetItem(locals, name);
+ if (v == NULL) {
+ if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError))
+ goto error;
+ _PyErr_Clear(tstate);
+ }
+ }
+ if (v == NULL) {
+ v = PyDict_GetItemWithError(f->f_globals, name);
+ if (v != NULL) {
+ Py_INCREF(v);
+ }
+ else if (_PyErr_Occurred(tstate)) {
+ goto error;
+ }
+ else {
+ if (PyDict_CheckExact(f->f_builtins)) {
+ v = PyDict_GetItemWithError(f->f_builtins, name);
+ if (v == NULL) {
+ if (!_PyErr_Occurred(tstate)) {
+ format_exc_check_arg(
+ tstate, PyExc_NameError,
+ NAME_ERROR_MSG, name);
+ }
+ goto error;
+ }
+ Py_INCREF(v);
+ }
+ else {
+ v = PyObject_GetItem(f->f_builtins, name);
+ if (v == NULL) {
+ if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
+ format_exc_check_arg(
+ tstate, PyExc_NameError,
+ NAME_ERROR_MSG, name);
+ }
+ goto error;
+ }
+ }
+ }
+ }
+ PUSH(v);
+ DISPATCH();
+ }
+
+ case TARGET(LOAD_GLOBAL): {
+ PyObject *name;
+ PyObject *v;
+ if (PyDict_CheckExact(f->f_globals)
+ && PyDict_CheckExact(f->f_builtins))
+ {
+ OPCACHE_CHECK();
+ if (co_opcache != NULL && co_opcache->optimized > 0) {
+ _PyOpcache_LoadGlobal *lg = &co_opcache->u.lg;
+
+ if (lg->globals_ver ==
+ ((PyDictObject *)f->f_globals)->ma_version_tag
+ && lg->builtins_ver ==
+ ((PyDictObject *)f->f_builtins)->ma_version_tag)
+ {
+ PyObject *ptr = lg->ptr;
+ OPCACHE_STAT_GLOBAL_HIT();
+ assert(ptr != NULL);
+ Py_INCREF(ptr);
+ PUSH(ptr);
+ DISPATCH();
+ }
+ }
+
+ name = GETITEM(names, oparg);
+ v = _PyDict_LoadGlobal((PyDictObject *)f->f_globals,
+ (PyDictObject *)f->f_builtins,
+ name);
+ if (v == NULL) {
+ if (!_PyErr_OCCURRED()) {
+ /* _PyDict_LoadGlobal() returns NULL without raising
+ * an exception if the key doesn't exist */
+ format_exc_check_arg(tstate, PyExc_NameError,
+ NAME_ERROR_MSG, name);
+ }
+ goto error;
+ }
+
+ if (co_opcache != NULL) {
+ _PyOpcache_LoadGlobal *lg = &co_opcache->u.lg;
+
+ if (co_opcache->optimized == 0) {
+ /* Wasn't optimized before. */
+ OPCACHE_STAT_GLOBAL_OPT();
+ } else {
+ OPCACHE_STAT_GLOBAL_MISS();
+ }
+
+ co_opcache->optimized = 1;
+ lg->globals_ver =
+ ((PyDictObject *)f->f_globals)->ma_version_tag;
+ lg->builtins_ver =
+ ((PyDictObject *)f->f_builtins)->ma_version_tag;
+ lg->ptr = v; /* borrowed */
+ }
+
+ Py_INCREF(v);
+ }
+ else {
+ /* Slow-path if globals or builtins is not a dict */
+
+ /* namespace 1: globals */
+ name = GETITEM(names, oparg);
+ v = PyObject_GetItem(f->f_globals, name);
+ if (v == NULL) {
+ if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
+ goto error;
+ }
+ _PyErr_Clear(tstate);
+
+ /* namespace 2: builtins */
+ v = PyObject_GetItem(f->f_builtins, name);
+ if (v == NULL) {
+ if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
+ format_exc_check_arg(
+ tstate, PyExc_NameError,
+ NAME_ERROR_MSG, name);
+ }
+ goto error;
+ }
+ }
+ }
+ PUSH(v);
+ DISPATCH();
+ }
+
+ case TARGET(DELETE_FAST): {
+ PyObject *v = GETLOCAL(oparg);
+ if (v != NULL) {
+ SETLOCAL(oparg, NULL);
+ DISPATCH();
+ }
+ format_exc_check_arg(
+ tstate, PyExc_UnboundLocalError,
+ UNBOUNDLOCAL_ERROR_MSG,
+ PyTuple_GetItem(co->co_varnames, oparg)
+ );
+ goto error;
+ }
+
+ case TARGET(DELETE_DEREF): {
+ PyObject *cell = freevars[oparg];
+ PyObject *oldobj = PyCell_GET(cell);
+ if (oldobj != NULL) {
+ PyCell_SET(cell, NULL);
+ Py_DECREF(oldobj);
+ DISPATCH();
+ }
+ format_exc_unbound(tstate, co, oparg);
+ goto error;
+ }
+
+ case TARGET(LOAD_CLOSURE): {
+ PyObject *cell = freevars[oparg];
+ Py_INCREF(cell);
+ PUSH(cell);
+ DISPATCH();
+ }
+
+ case TARGET(LOAD_CLASSDEREF): {
+ PyObject *name, *value, *locals = f->f_locals;
+ Py_ssize_t idx;
+ assert(locals);
+ assert(oparg >= PyTuple_GET_SIZE(co->co_cellvars));
+ idx = oparg - PyTuple_GET_SIZE(co->co_cellvars);
+ assert(idx >= 0 && idx < PyTuple_GET_SIZE(co->co_freevars));
+ name = PyTuple_GET_ITEM(co->co_freevars, idx);
+ if (PyDict_CheckExact(locals)) {
+ value = PyDict_GetItemWithError(locals, name);
+ if (value != NULL) {
+ Py_INCREF(value);
+ }
+ else if (_PyErr_Occurred(tstate)) {
+ goto error;
+ }
+ }
+ else {
+ value = PyObject_GetItem(locals, name);
+ if (value == NULL) {
+ if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
+ goto error;
+ }
+ _PyErr_Clear(tstate);
+ }
+ }
+ if (!value) {
+ PyObject *cell = freevars[oparg];
+ value = PyCell_GET(cell);
+ if (value == NULL) {
+ format_exc_unbound(tstate, co, oparg);
+ goto error;
+ }
+ Py_INCREF(value);
+ }
+ PUSH(value);
+ DISPATCH();
+ }
+
+ case TARGET(LOAD_DEREF): {
+ PyObject *cell = freevars[oparg];
+ PyObject *value = PyCell_GET(cell);
+ if (value == NULL) {
+ format_exc_unbound(tstate, co, oparg);
+ goto error;
+ }
+ Py_INCREF(value);
+ PUSH(value);
+ DISPATCH();
+ }
+
+ case TARGET(STORE_DEREF): {
+ PyObject *v = POP();
+ PyObject *cell = freevars[oparg];
+ PyObject *oldobj = PyCell_GET(cell);
+ PyCell_SET(cell, v);
+ Py_XDECREF(oldobj);
+ DISPATCH();
+ }
+
+ case TARGET(BUILD_STRING): {
+ PyObject *str;
+ PyObject *empty = PyUnicode_New(0, 0);
+ if (empty == NULL) {
+ goto error;
+ }
+ str = _PyUnicode_JoinArray(empty, stack_pointer - oparg, oparg);
+ Py_DECREF(empty);
+ if (str == NULL)
+ goto error;
+ while (--oparg >= 0) {
+ PyObject *item = POP();
+ Py_DECREF(item);
+ }
+ PUSH(str);
+ DISPATCH();
+ }
+
+ case TARGET(BUILD_TUPLE): {
+ PyObject *tup = PyTuple_New(oparg);
+ if (tup == NULL)
+ goto error;
+ while (--oparg >= 0) {
+ PyObject *item = POP();
+ PyTuple_SET_ITEM(tup, oparg, item);
+ }
+ PUSH(tup);
+ DISPATCH();
+ }
+
+ case TARGET(BUILD_LIST): {
+ PyObject *list = PyList_New(oparg);
+ if (list == NULL)
+ goto error;
+ while (--oparg >= 0) {
+ PyObject *item = POP();
+ PyList_SET_ITEM(list, oparg, item);
+ }
+ PUSH(list);
+ DISPATCH();
+ }
+
+ case TARGET(LIST_TO_TUPLE): {
+ PyObject *list = POP();
+ PyObject *tuple = PyList_AsTuple(list);
+ Py_DECREF(list);
+ if (tuple == NULL) {
+ goto error;
+ }
+ PUSH(tuple);
+ DISPATCH();
+ }
+
+ case TARGET(LIST_EXTEND): {
+ PyObject *iterable = POP();
+ PyObject *list = PEEK(oparg);
+ PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable);
+ if (none_val == NULL) {
+ if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) &&
+ (Py_TYPE(iterable)->tp_iter == NULL && !PySequence_Check(iterable)))
+ {
+ _PyErr_Clear(tstate);
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "Value after * must be an iterable, not %.200s",
+ Py_TYPE(iterable)->tp_name);
+ }
+ Py_DECREF(iterable);
+ goto error;
+ }
+ Py_DECREF(none_val);
+ Py_DECREF(iterable);
+ DISPATCH();
+ }
+
+ case TARGET(SET_UPDATE): {
+ PyObject *iterable = POP();
+ PyObject *set = PEEK(oparg);
+ int err = _PySet_Update(set, iterable);
+ Py_DECREF(iterable);
+ if (err < 0) {
+ goto error;
+ }
+ DISPATCH();
+ }
+
+ case TARGET(BUILD_SET): {
+ PyObject *set = PySet_New(NULL);
+ int err = 0;
+ int i;
+ if (set == NULL)
+ goto error;
+ for (i = oparg; i > 0; i--) {
+ PyObject *item = PEEK(i);
+ if (err == 0)
+ err = PySet_Add(set, item);
+ Py_DECREF(item);
+ }
+ STACK_SHRINK(oparg);
+ if (err != 0) {
+ Py_DECREF(set);
+ goto error;
+ }
+ PUSH(set);
+ DISPATCH();
+ }
+
+ case TARGET(BUILD_MAP): {
+ Py_ssize_t i;
+ PyObject *map = _PyDict_NewPresized((Py_ssize_t)oparg);
+ if (map == NULL)
+ goto error;
+ for (i = oparg; i > 0; i--) {
+ int err;
+ PyObject *key = PEEK(2*i);
+ PyObject *value = PEEK(2*i - 1);
+ err = PyDict_SetItem(map, key, value);
+ if (err != 0) {
+ Py_DECREF(map);
+ goto error;
+ }
+ }
+
+ while (oparg--) {
+ Py_DECREF(POP());
+ Py_DECREF(POP());
+ }
+ PUSH(map);
+ DISPATCH();
+ }
+
+ case TARGET(SETUP_ANNOTATIONS): {
+ _Py_IDENTIFIER(__annotations__);
+ int err;
+ PyObject *ann_dict;
+ if (f->f_locals == NULL) {
+ _PyErr_Format(tstate, PyExc_SystemError,
+ "no locals found when setting up annotations");
+ goto error;
+ }
+ /* check if __annotations__ in locals()... */
+ if (PyDict_CheckExact(f->f_locals)) {
+ ann_dict = _PyDict_GetItemIdWithError(f->f_locals,
+ &PyId___annotations__);
+ if (ann_dict == NULL) {
+ if (_PyErr_Occurred(tstate)) {
+ goto error;
+ }
+ /* ...if not, create a new one */
+ ann_dict = PyDict_New();
+ if (ann_dict == NULL) {
+ goto error;
+ }
+ err = _PyDict_SetItemId(f->f_locals,
+ &PyId___annotations__, ann_dict);
+ Py_DECREF(ann_dict);
+ if (err != 0) {
+ goto error;
+ }
+ }
+ }
+ else {
+ /* do the same if locals() is not a dict */
+ PyObject *ann_str = _PyUnicode_FromId(&PyId___annotations__);
+ if (ann_str == NULL) {
+ goto error;
+ }
+ ann_dict = PyObject_GetItem(f->f_locals, ann_str);
+ if (ann_dict == NULL) {
+ if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
+ goto error;
+ }
+ _PyErr_Clear(tstate);
+ ann_dict = PyDict_New();
+ if (ann_dict == NULL) {
+ goto error;
+ }
+ err = PyObject_SetItem(f->f_locals, ann_str, ann_dict);
+ Py_DECREF(ann_dict);
+ if (err != 0) {
+ goto error;
+ }
+ }
+ else {
+ Py_DECREF(ann_dict);
+ }
+ }
+ DISPATCH();
+ }
+
+ case TARGET(BUILD_CONST_KEY_MAP): {
+ Py_ssize_t i;
+ PyObject *map;
+ PyObject *keys = TOP();
+ if (!PyTuple_CheckExact(keys) ||
+ PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) {
+ _PyErr_SetString(tstate, PyExc_SystemError,
+ "bad BUILD_CONST_KEY_MAP keys argument");
+ goto error;
+ }
+ map = _PyDict_NewPresized((Py_ssize_t)oparg);
+ if (map == NULL) {
+ goto error;
+ }
+ for (i = oparg; i > 0; i--) {
+ int err;
+ PyObject *key = PyTuple_GET_ITEM(keys, oparg - i);
+ PyObject *value = PEEK(i + 1);
+ err = PyDict_SetItem(map, key, value);
+ if (err != 0) {
+ Py_DECREF(map);
+ goto error;
+ }
+ }
+
+ Py_DECREF(POP());
+ while (oparg--) {
+ Py_DECREF(POP());
+ }
+ PUSH(map);
+ DISPATCH();
+ }
+
+ case TARGET(DICT_UPDATE): {
+ PyObject *update = POP();
+ PyObject *dict = PEEK(oparg);
+ if (PyDict_Update(dict, update) < 0) {
+ if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "'%.200s' object is not a mapping",
+ Py_TYPE(update)->tp_name);
+ }
+ Py_DECREF(update);
+ goto error;
+ }
+ Py_DECREF(update);
+ DISPATCH();
+ }
+
+ case TARGET(DICT_MERGE): {
+ PyObject *update = POP();
+ PyObject *dict = PEEK(oparg);
+
+ if (_PyDict_MergeEx(dict, update, 2) < 0) {
+ format_kwargs_error(tstate, PEEK(2 + oparg), update);
+ Py_DECREF(update);
+ goto error;
+ }
+ Py_DECREF(update);
+ PREDICT(CALL_FUNCTION_EX);
+ DISPATCH();
+ }
+
+ case TARGET(MAP_ADD): {
+ PyObject *value = TOP();
+ PyObject *key = SECOND();
+ PyObject *map;
+ int err;
+ STACK_SHRINK(2);
+ map = PEEK(oparg); /* dict */
+ assert(PyDict_CheckExact(map));
+ err = PyDict_SetItem(map, key, value); /* map[key] = value */
+ Py_DECREF(value);
+ Py_DECREF(key);
+ if (err != 0)
+ goto error;
+ PREDICT(JUMP_ABSOLUTE);
+ DISPATCH();
+ }
+
+ case TARGET(LOAD_ATTR): {
+ PyObject *name = GETITEM(names, oparg);
+ PyObject *owner = TOP();
+ PyObject *res = PyObject_GetAttr(owner, name);
+ Py_DECREF(owner);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(COMPARE_OP): {
+ assert(oparg <= Py_GE);
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyObject_RichCompare(left, right, oparg);
+ SET_TOP(res);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ if (res == NULL)
+ goto error;
+ PREDICT(POP_JUMP_IF_FALSE);
+ PREDICT(POP_JUMP_IF_TRUE);
+ DISPATCH();
+ }
+
+ case TARGET(IS_OP): {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ int res = (left == right)^oparg;
+ PyObject *b = res ? Py_True : Py_False;
+ Py_INCREF(b);
+ SET_TOP(b);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ PREDICT(POP_JUMP_IF_FALSE);
+ PREDICT(POP_JUMP_IF_TRUE);
+ FAST_DISPATCH();
+ }
+
+ case TARGET(CONTAINS_OP): {
+ PyObject *right = POP();
+ PyObject *left = POP();
+ int res = PySequence_Contains(right, left);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ if (res < 0) {
+ goto error;
+ }
+ PyObject *b = (res^oparg) ? Py_True : Py_False;
+ Py_INCREF(b);
+ PUSH(b);
+ PREDICT(POP_JUMP_IF_FALSE);
+ PREDICT(POP_JUMP_IF_TRUE);
+ FAST_DISPATCH();
+ }
+
+#define CANNOT_CATCH_MSG "catching classes that do not inherit from "\
+ "BaseException is not allowed"
+
+ case TARGET(JUMP_IF_NOT_EXC_MATCH): {
+ PyObject *right = POP();
+ PyObject *left = POP();
+ if (PyTuple_Check(right)) {
+ Py_ssize_t i, length;
+ length = PyTuple_GET_SIZE(right);
+ for (i = 0; i < length; i++) {
+ PyObject *exc = PyTuple_GET_ITEM(right, i);
+ if (!PyExceptionClass_Check(exc)) {
+ _PyErr_SetString(tstate, PyExc_TypeError,
+ CANNOT_CATCH_MSG);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ goto error;
+ }
+ }
+ }
+ else {
+ if (!PyExceptionClass_Check(right)) {
+ _PyErr_SetString(tstate, PyExc_TypeError,
+ CANNOT_CATCH_MSG);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ goto error;
+ }
+ }
+ int res = PyErr_GivenExceptionMatches(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ if (res > 0) {
+ /* Exception matches -- Do nothing */;
+ }
+ else if (res == 0) {
+ JUMPTO(oparg);
+ }
+ else {
+ goto error;
+ }
+ DISPATCH();
+ }
+
+ case TARGET(IMPORT_NAME): {
+ PyObject *name = GETITEM(names, oparg);
+ PyObject *fromlist = POP();
+ PyObject *level = TOP();
+ PyObject *res;
+ res = import_name(tstate, f, name, fromlist, level);
+ Py_DECREF(level);
+ Py_DECREF(fromlist);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(IMPORT_STAR): {
+ PyObject *from = POP(), *locals;
+ int err;
+ if (PyFrame_FastToLocalsWithError(f) < 0) {
+ Py_DECREF(from);
+ goto error;
+ }
+
+ locals = f->f_locals;
+ if (locals == NULL) {
+ _PyErr_SetString(tstate, PyExc_SystemError,
+ "no locals found during 'import *'");
+ Py_DECREF(from);
+ goto error;
+ }
+ err = import_all_from(tstate, locals, from);
+ PyFrame_LocalsToFast(f, 0);
+ Py_DECREF(from);
+ if (err != 0)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(IMPORT_FROM): {
+ PyObject *name = GETITEM(names, oparg);
+ PyObject *from = TOP();
+ PyObject *res;
+ res = import_from(tstate, from, name);
+ PUSH(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(JUMP_FORWARD): {
+ JUMPBY(oparg);
+ FAST_DISPATCH();
+ }
+
+ case TARGET(POP_JUMP_IF_FALSE): {
+ PREDICTED(POP_JUMP_IF_FALSE);
+ PyObject *cond = POP();
+ int err;
+ if (cond == Py_True) {
+ Py_DECREF(cond);
+ FAST_DISPATCH();
+ }
+ if (cond == Py_False) {
+ Py_DECREF(cond);
+ JUMPTO(oparg);
+ FAST_DISPATCH();
+ }
+ err = PyObject_IsTrue(cond);
+ Py_DECREF(cond);
+ if (err > 0)
+ ;
+ else if (err == 0)
+ JUMPTO(oparg);
+ else
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(POP_JUMP_IF_TRUE): {
+ PREDICTED(POP_JUMP_IF_TRUE);
+ PyObject *cond = POP();
+ int err;
+ if (cond == Py_False) {
+ Py_DECREF(cond);
+ FAST_DISPATCH();
+ }
+ if (cond == Py_True) {
+ Py_DECREF(cond);
+ JUMPTO(oparg);
+ FAST_DISPATCH();
+ }
+ err = PyObject_IsTrue(cond);
+ Py_DECREF(cond);
+ if (err > 0) {
+ JUMPTO(oparg);
+ }
+ else if (err == 0)
+ ;
+ else
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(JUMP_IF_FALSE_OR_POP): {
+ PyObject *cond = TOP();
+ int err;
+ if (cond == Py_True) {
+ STACK_SHRINK(1);
+ Py_DECREF(cond);
+ FAST_DISPATCH();
+ }
+ if (cond == Py_False) {
+ JUMPTO(oparg);
+ FAST_DISPATCH();
+ }
+ err = PyObject_IsTrue(cond);
+ if (err > 0) {
+ STACK_SHRINK(1);
+ Py_DECREF(cond);
+ }
+ else if (err == 0)
+ JUMPTO(oparg);
+ else
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(JUMP_IF_TRUE_OR_POP): {
+ PyObject *cond = TOP();
+ int err;
+ if (cond == Py_False) {
+ STACK_SHRINK(1);
+ Py_DECREF(cond);
+ FAST_DISPATCH();
+ }
+ if (cond == Py_True) {
+ JUMPTO(oparg);
+ FAST_DISPATCH();
+ }
+ err = PyObject_IsTrue(cond);
+ if (err > 0) {
+ JUMPTO(oparg);
+ }
+ else if (err == 0) {
+ STACK_SHRINK(1);
+ Py_DECREF(cond);
+ }
+ else
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(JUMP_ABSOLUTE): {
+ PREDICTED(JUMP_ABSOLUTE);
+ JUMPTO(oparg);
+#if FAST_LOOPS
+ /* Enabling this path speeds-up all while and for-loops by bypassing
+ the per-loop checks for signals. By default, this should be turned-off
+ because it prevents detection of a control-break in tight loops like
+ "while 1: pass". Compile with this option turned-on when you need
+ the speed-up and do not need break checking inside tight loops (ones
+ that contain only instructions ending with FAST_DISPATCH).
+ */
+ FAST_DISPATCH();
+#else
+ DISPATCH();
+#endif
+ }
+
+ case TARGET(GET_ITER): {
+ /* before: [obj]; after [getiter(obj)] */
+ PyObject *iterable = TOP();
+ PyObject *iter = PyObject_GetIter(iterable);
+ Py_DECREF(iterable);
+ SET_TOP(iter);
+ if (iter == NULL)
+ goto error;
+ PREDICT(FOR_ITER);
+ PREDICT(CALL_FUNCTION);
+ DISPATCH();
+ }
+
+ case TARGET(GET_YIELD_FROM_ITER): {
+ /* before: [obj]; after [getiter(obj)] */
+ PyObject *iterable = TOP();
+ PyObject *iter;
+ if (PyCoro_CheckExact(iterable)) {
+ /* `iterable` is a coroutine */
+ if (!(co->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE))) {
+ /* and it is used in a 'yield from' expression of a
+ regular generator. */
+ Py_DECREF(iterable);
+ SET_TOP(NULL);
+ _PyErr_SetString(tstate, PyExc_TypeError,
+ "cannot 'yield from' a coroutine object "
+ "in a non-coroutine generator");
+ goto error;
+ }
+ }
+ else if (!PyGen_CheckExact(iterable)) {
+ /* `iterable` is not a generator. */
+ iter = PyObject_GetIter(iterable);
+ Py_DECREF(iterable);
+ SET_TOP(iter);
+ if (iter == NULL)
+ goto error;
+ }
+ PREDICT(LOAD_CONST);
+ DISPATCH();
+ }
+
+ case TARGET(FOR_ITER): {
+ PREDICTED(FOR_ITER);
+ /* before: [iter]; after: [iter, iter()] *or* [] */
+ PyObject *iter = TOP();
+ PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter);
+ if (next != NULL) {
+ PUSH(next);
+ PREDICT(STORE_FAST);
+ PREDICT(UNPACK_SEQUENCE);
+ DISPATCH();
+ }
+ if (_PyErr_Occurred(tstate)) {
+ if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) {
+ goto error;
+ }
+ else if (tstate->c_tracefunc != NULL) {
+ call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f);
+ }
+ _PyErr_Clear(tstate);
+ }
+ /* iterator ended normally */
+ STACK_SHRINK(1);
+ Py_DECREF(iter);
+ JUMPBY(oparg);
+ PREDICT(POP_BLOCK);
+ DISPATCH();
+ }
+
+ case TARGET(SETUP_FINALLY): {
+ PyFrame_BlockSetup(f, SETUP_FINALLY, INSTR_OFFSET() + oparg,
+ STACK_LEVEL());
+ DISPATCH();
+ }
+
+ case TARGET(BEFORE_ASYNC_WITH): {
+ _Py_IDENTIFIER(__aenter__);
+ _Py_IDENTIFIER(__aexit__);
+ PyObject *mgr = TOP();
+ PyObject *enter = special_lookup(tstate, mgr, &PyId___aenter__);
+ PyObject *res;
+ if (enter == NULL) {
+ goto error;
+ }
+ PyObject *exit = special_lookup(tstate, mgr, &PyId___aexit__);
+ if (exit == NULL) {
+ Py_DECREF(enter);
+ goto error;
+ }
+ SET_TOP(exit);
+ Py_DECREF(mgr);
+ res = _PyObject_CallNoArg(enter);
+ Py_DECREF(enter);
+ if (res == NULL)
+ goto error;
+ PUSH(res);
+ PREDICT(GET_AWAITABLE);
+ DISPATCH();
+ }
+
+ case TARGET(SETUP_ASYNC_WITH): {
+ PyObject *res = POP();
+ /* Setup the finally block before pushing the result
+ of __aenter__ on the stack. */
+ PyFrame_BlockSetup(f, SETUP_FINALLY, INSTR_OFFSET() + oparg,
+ STACK_LEVEL());
+ PUSH(res);
+ DISPATCH();
+ }
+
+ case TARGET(SETUP_WITH): {
+ _Py_IDENTIFIER(__enter__);
+ _Py_IDENTIFIER(__exit__);
+ PyObject *mgr = TOP();
+ PyObject *enter = special_lookup(tstate, mgr, &PyId___enter__);
+ PyObject *res;
+ if (enter == NULL) {
+ goto error;
+ }
+ PyObject *exit = special_lookup(tstate, mgr, &PyId___exit__);
+ if (exit == NULL) {
+ Py_DECREF(enter);
+ goto error;
+ }
+ SET_TOP(exit);
+ Py_DECREF(mgr);
+ res = _PyObject_CallNoArg(enter);
+ Py_DECREF(enter);
+ if (res == NULL)
+ goto error;
+ /* Setup the finally block before pushing the result
+ of __enter__ on the stack. */
+ PyFrame_BlockSetup(f, SETUP_FINALLY, INSTR_OFFSET() + oparg,
+ STACK_LEVEL());
+
+ PUSH(res);
+ DISPATCH();
+ }
+
+ case TARGET(WITH_EXCEPT_START): {
+ /* At the top of the stack are 7 values:
+ - (TOP, SECOND, THIRD) = exc_info()
+ - (FOURTH, FIFTH, SIXTH) = previous exception for EXCEPT_HANDLER
+ - SEVENTH: the context.__exit__ bound method
+ We call SEVENTH(TOP, SECOND, THIRD).
+ Then we push again the TOP exception and the __exit__
+ return value.
+ */
+ PyObject *exit_func;
+ PyObject *exc, *val, *tb, *res;
+
+ exc = TOP();
+ val = SECOND();
+ tb = THIRD();
+ assert(exc != Py_None);
+ assert(!PyLong_Check(exc));
+ exit_func = PEEK(7);
+ PyObject *stack[4] = {NULL, exc, val, tb};
+ res = PyObject_Vectorcall(exit_func, stack + 1,
+ 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
+ if (res == NULL)
+ goto error;
+
+ PUSH(res);
+ DISPATCH();
+ }
+
+ case TARGET(LOAD_METHOD): {
+ /* Designed to work in tandem with CALL_METHOD. */
+ PyObject *name = GETITEM(names, oparg);
+ PyObject *obj = TOP();
+ PyObject *meth = NULL;
+
+ int meth_found = _PyObject_GetMethod(obj, name, &meth);
+
+ if (meth == NULL) {
+ /* Most likely attribute wasn't found. */
+ goto error;
+ }
+
+ if (meth_found) {
+ /* We can bypass temporary bound method object.
+ meth is unbound method and obj is self.
+
+ meth | self | arg1 | ... | argN
+ */
+ SET_TOP(meth);
+ PUSH(obj); // self
+ }
+ 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_METHOD that it's not a method call.
+
+ NULL | meth | arg1 | ... | argN
+ */
+ SET_TOP(NULL);
+ Py_DECREF(obj);
+ PUSH(meth);
+ }
+ DISPATCH();
+ }
+
+ case TARGET(CALL_METHOD): {
+ /* Designed to work in tamdem with LOAD_METHOD. */
+ PyObject **sp, *res, *meth;
+
+ sp = stack_pointer;
+
+ meth = PEEK(oparg + 2);
+ if (meth == NULL) {
+ /* `meth` is NULL when LOAD_METHOD thinks that it's not
+ a method call.
+
+ Stack layout:
+
+ ... | NULL | callable | arg1 | ... | argN
+ ^- TOP()
+ ^- (-oparg)
+ ^- (-oparg-1)
+ ^- (-oparg-2)
+
+ `callable` will be POPed by call_function.
+ NULL will will be POPed manually later.
+ */
+ res = call_function(tstate, &sp, oparg, NULL);
+ stack_pointer = sp;
+ (void)POP(); /* POP the NULL. */
+ }
+ else {
+ /* This is a method call. Stack layout:
+
+ ... | method | self | arg1 | ... | argN
+ ^- TOP()
+ ^- (-oparg)
+ ^- (-oparg-1)
+ ^- (-oparg-2)
+
+ `self` and `method` will be POPed by call_function.
+ We'll be passing `oparg + 1` to call_function, to
+ make it accept the `self` as a first argument.
+ */
+ res = call_function(tstate, &sp, oparg + 1, NULL);
+ stack_pointer = sp;
+ }
+
+ PUSH(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(CALL_FUNCTION): {
+ PREDICTED(CALL_FUNCTION);
+ PyObject **sp, *res;
+ sp = stack_pointer;
+ res = call_function(tstate, &sp, oparg, NULL);
+ stack_pointer = sp;
+ PUSH(res);
+ if (res == NULL) {
+ goto error;
+ }
+ DISPATCH();
+ }
+
+ case TARGET(CALL_FUNCTION_KW): {
+ PyObject **sp, *res, *names;
+
+ names = POP();
+ assert(PyTuple_Check(names));
+ assert(PyTuple_GET_SIZE(names) <= oparg);
+ /* We assume without checking that names contains only strings */
+ sp = stack_pointer;
+ res = call_function(tstate, &sp, oparg, names);
+ stack_pointer = sp;
+ PUSH(res);
+ Py_DECREF(names);
+
+ if (res == NULL) {
+ goto error;
+ }
+ DISPATCH();
+ }
+
+ case TARGET(CALL_FUNCTION_EX): {
+ PREDICTED(CALL_FUNCTION_EX);
+ PyObject *func, *callargs, *kwargs = NULL, *result;
+ if (oparg & 0x01) {
+ kwargs = POP();
+ if (!PyDict_CheckExact(kwargs)) {
+ PyObject *d = PyDict_New();
+ if (d == NULL)
+ goto error;
+ if (_PyDict_MergeEx(d, kwargs, 2) < 0) {
+ Py_DECREF(d);
+ format_kwargs_error(tstate, SECOND(), kwargs);
+ Py_DECREF(kwargs);
+ goto error;
+ }
+ Py_DECREF(kwargs);
+ kwargs = d;
+ }
+ assert(PyDict_CheckExact(kwargs));
+ }
+ callargs = POP();
+ func = TOP();
+ if (!PyTuple_CheckExact(callargs)) {
+ if (check_args_iterable(tstate, func, callargs) < 0) {
+ Py_DECREF(callargs);
+ goto error;
+ }
+ Py_SETREF(callargs, PySequence_Tuple(callargs));
+ if (callargs == NULL) {
+ goto error;
+ }
+ }
+ assert(PyTuple_CheckExact(callargs));
+
+ result = do_call_core(tstate, func, callargs, kwargs);
+ Py_DECREF(func);
+ Py_DECREF(callargs);
+ Py_XDECREF(kwargs);
+
+ SET_TOP(result);
+ if (result == NULL) {
+ goto error;
+ }
+ DISPATCH();
+ }
+
+ case TARGET(MAKE_FUNCTION): {
+ PyObject *qualname = POP();
+ PyObject *codeobj = POP();
+ PyFunctionObject *func = (PyFunctionObject *)
+ PyFunction_NewWithQualName(codeobj, f->f_globals, qualname);
+
+ Py_DECREF(codeobj);
+ Py_DECREF(qualname);
+ if (func == NULL) {
+ goto error;
+ }
+
+ if (oparg & 0x08) {
+ assert(PyTuple_CheckExact(TOP()));
+ func ->func_closure = POP();
+ }
+ if (oparg & 0x04) {
+ assert(PyDict_CheckExact(TOP()));
+ func->func_annotations = POP();
+ }
+ if (oparg & 0x02) {
+ assert(PyDict_CheckExact(TOP()));
+ func->func_kwdefaults = POP();
+ }
+ if (oparg & 0x01) {
+ assert(PyTuple_CheckExact(TOP()));
+ func->func_defaults = POP();
+ }
+
+ PUSH((PyObject *)func);
+ DISPATCH();
+ }
+
+ case TARGET(BUILD_SLICE): {
+ PyObject *start, *stop, *step, *slice;
+ if (oparg == 3)
+ step = POP();
+ else
+ step = NULL;
+ stop = POP();
+ start = TOP();
+ slice = PySlice_New(start, stop, step);
+ Py_DECREF(start);
+ Py_DECREF(stop);
+ Py_XDECREF(step);
+ SET_TOP(slice);
+ if (slice == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ case TARGET(FORMAT_VALUE): {
+ /* Handles f-string value formatting. */
+ PyObject *result;
+ PyObject *fmt_spec;
+ PyObject *value;
+ PyObject *(*conv_fn)(PyObject *);
+ int which_conversion = oparg & FVC_MASK;
+ int have_fmt_spec = (oparg & FVS_MASK) == FVS_HAVE_SPEC;
+
+ fmt_spec = have_fmt_spec ? POP() : NULL;
+ value = POP();
+
+ /* See if any conversion is specified. */
+ switch (which_conversion) {
+ case FVC_NONE: conv_fn = NULL; break;
+ case FVC_STR: conv_fn = PyObject_Str; break;
+ case FVC_REPR: conv_fn = PyObject_Repr; break;
+ case FVC_ASCII: conv_fn = PyObject_ASCII; break;
+ default:
+ _PyErr_Format(tstate, PyExc_SystemError,
+ "unexpected conversion flag %d",
+ which_conversion);
+ goto error;
+ }
+
+ /* If there's a conversion function, call it and replace
+ value with that result. Otherwise, just use value,
+ without conversion. */
+ if (conv_fn != NULL) {
+ result = conv_fn(value);
+ Py_DECREF(value);
+ if (result == NULL) {
+ Py_XDECREF(fmt_spec);
+ goto error;
+ }
+ value = result;
+ }
+
+ /* If value is a unicode object, and there's no fmt_spec,
+ then we know the result of format(value) is value
+ itself. In that case, skip calling format(). I plan to
+ move this optimization in to PyObject_Format()
+ itself. */
+ if (PyUnicode_CheckExact(value) && fmt_spec == NULL) {
+ /* Do nothing, just transfer ownership to result. */
+ result = value;
+ } else {
+ /* Actually call format(). */
+ result = PyObject_Format(value, fmt_spec);
+ Py_DECREF(value);
+ Py_XDECREF(fmt_spec);
+ if (result == NULL) {
+ goto error;
+ }
+ }
+
+ PUSH(result);
+ DISPATCH();
+ }
+
+ case TARGET(EXTENDED_ARG): {
+ int oldoparg = oparg;
+ NEXTOPARG();
+ oparg |= oldoparg << 8;
+ goto dispatch_opcode;
+ }
+
+
+#if USE_COMPUTED_GOTOS
+ _unknown_opcode:
+#endif
+ default:
+ fprintf(stderr,
+ "XXX lineno: %d, opcode: %d\n",
+ PyFrame_GetLineNumber(f),
+ opcode);
+ _PyErr_SetString(tstate, PyExc_SystemError, "unknown opcode");
+ goto error;
+
+ } /* switch */
+
+ /* This should never be reached. Every opcode should end with DISPATCH()
+ or goto error. */
+ Py_UNREACHABLE();
+
+error:
+ /* Double-check exception status. */
+#ifdef NDEBUG
+ if (!_PyErr_Occurred(tstate)) {
+ _PyErr_SetString(tstate, PyExc_SystemError,
+ "error return without exception set");
+ }
+#else
+ assert(_PyErr_Occurred(tstate));
+#endif
+
+ /* Log traceback info. */
+ PyTraceBack_Here(f);
+
+ if (tstate->c_tracefunc != NULL)
+ call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj,
+ tstate, f);
+
+exception_unwind:
+ /* Unwind stacks if an exception occurred */
+ while (f->f_iblock > 0) {
+ /* Pop the current block. */
+ PyTryBlock *b = &f->f_blockstack[--f->f_iblock];
+
+ if (b->b_type == EXCEPT_HANDLER) {
+ UNWIND_EXCEPT_HANDLER(b);
+ continue;
+ }
+ UNWIND_BLOCK(b);
+ if (b->b_type == SETUP_FINALLY) {
+ PyObject *exc, *val, *tb;
+ int handler = b->b_handler;
+ _PyErr_StackItem *exc_info = tstate->exc_info;
+ /* Beware, this invalidates all b->b_* fields */
+ PyFrame_BlockSetup(f, EXCEPT_HANDLER, -1, STACK_LEVEL());
+ PUSH(exc_info->exc_traceback);
+ PUSH(exc_info->exc_value);
+ if (exc_info->exc_type != NULL) {
+ PUSH(exc_info->exc_type);
+ }
+ else {
+ Py_INCREF(Py_None);
+ PUSH(Py_None);
+ }
+ _PyErr_Fetch(tstate, &exc, &val, &tb);
+ /* Make the raw exception data
+ available to the handler,
+ so a program can emulate the
+ Python main loop. */
+ _PyErr_NormalizeException(tstate, &exc, &val, &tb);
+ if (tb != NULL)
+ PyException_SetTraceback(val, tb);
+ else
+ PyException_SetTraceback(val, Py_None);
+ Py_INCREF(exc);
+ exc_info->exc_type = exc;
+ Py_INCREF(val);
+ exc_info->exc_value = val;
+ exc_info->exc_traceback = tb;
+ if (tb == NULL)
+ tb = Py_None;
+ Py_INCREF(tb);
+ PUSH(tb);
+ PUSH(val);
+ PUSH(exc);
+ JUMPTO(handler);
+ if (_Py_TracingPossible(ceval2)) {
+ int needs_new_execution_window = (f->f_lasti < instr_lb || f->f_lasti >= instr_ub);
+ int needs_line_update = (f->f_lasti == instr_lb || f->f_lasti < instr_prev);
+ /* Make sure that we trace line after exception if we are in a new execution
+ * window or we don't need a line update and we are not in the first instruction
+ * of the line. */
+ if (needs_new_execution_window || (!needs_line_update && instr_lb > 0)) {
+ instr_prev = INT_MAX;
+ }
+ }
+ /* Resume normal execution */
+ goto main_loop;
+ }
+ } /* unwind stack */
+
+ /* End the loop as we still have an error */
+ break;
+ } /* main loop */
+
+ assert(retval == NULL);
+ assert(_PyErr_Occurred(tstate));
+
+ /* Pop remaining stack entries. */
+ while (!EMPTY()) {
+ PyObject *o = POP();
+ Py_XDECREF(o);
+ }
+
+exiting:
+ if (tstate->use_tracing) {
+ if (tstate->c_tracefunc) {
+ if (call_trace_protected(tstate->c_tracefunc, tstate->c_traceobj,
+ tstate, f, PyTrace_RETURN, retval)) {
+ Py_CLEAR(retval);
+ }
+ }
+ if (tstate->c_profilefunc) {
+ if (call_trace_protected(tstate->c_profilefunc, tstate->c_profileobj,
+ tstate, f, PyTrace_RETURN, retval)) {
+ Py_CLEAR(retval);
+ }
+ }
+ }
+
+ /* pop frame */
+exit_eval_frame:
+ if (PyDTrace_FUNCTION_RETURN_ENABLED())
+ dtrace_function_return(f);
+ _Py_LeaveRecursiveCall(tstate);
+ f->f_executing = 0;
+ tstate->frame = f->f_back;
+
+ return _Py_CheckFunctionResult(tstate, NULL, retval, __func__);
+}
+
+static void
+format_missing(PyThreadState *tstate, const char *kind,
+ PyCodeObject *co, PyObject *names)
+{
+ int err;
+ Py_ssize_t len = PyList_GET_SIZE(names);
+ PyObject *name_str, *comma, *tail, *tmp;
+
+ assert(PyList_CheckExact(names));
+ assert(len >= 1);
+ /* Deal with the joys of natural language. */
+ switch (len) {
+ case 1:
+ name_str = PyList_GET_ITEM(names, 0);
+ Py_INCREF(name_str);
+ break;
+ case 2:
+ name_str = PyUnicode_FromFormat("%U and %U",
+ PyList_GET_ITEM(names, len - 2),
+ PyList_GET_ITEM(names, len - 1));
+ break;
+ default:
+ tail = PyUnicode_FromFormat(", %U, and %U",
+ PyList_GET_ITEM(names, len - 2),
+ PyList_GET_ITEM(names, len - 1));
+ if (tail == NULL)
+ return;
+ /* Chop off the last two objects in the list. This shouldn't actually
+ fail, but we can't be too careful. */
+ err = PyList_SetSlice(names, len - 2, len, NULL);
+ if (err == -1) {
+ Py_DECREF(tail);
+ return;
+ }
+ /* Stitch everything up into a nice comma-separated list. */
+ comma = PyUnicode_FromString(", ");
+ if (comma == NULL) {
+ Py_DECREF(tail);
+ return;
+ }
+ tmp = PyUnicode_Join(comma, names);
+ Py_DECREF(comma);
+ if (tmp == NULL) {
+ Py_DECREF(tail);
+ return;
+ }
+ name_str = PyUnicode_Concat(tmp, tail);
+ Py_DECREF(tmp);
+ Py_DECREF(tail);
+ break;
+ }
+ if (name_str == NULL)
+ return;
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "%U() missing %i required %s argument%s: %U",
+ co->co_name,
+ len,
+ kind,
+ len == 1 ? "" : "s",
+ name_str);
+ Py_DECREF(name_str);
+}
+
+static void
+missing_arguments(PyThreadState *tstate, PyCodeObject *co,
+ Py_ssize_t missing, Py_ssize_t defcount,
+ PyObject **fastlocals)
+{
+ Py_ssize_t i, j = 0;
+ Py_ssize_t start, end;
+ int positional = (defcount != -1);
+ const char *kind = positional ? "positional" : "keyword-only";
+ PyObject *missing_names;
+
+ /* Compute the names of the arguments that are missing. */
+ missing_names = PyList_New(missing);
+ if (missing_names == NULL)
+ return;
+ if (positional) {
+ start = 0;
+ end = co->co_argcount - defcount;
+ }
+ else {
+ start = co->co_argcount;
+ end = start + co->co_kwonlyargcount;
+ }
+ for (i = start; i < end; i++) {
+ if (GETLOCAL(i) == NULL) {
+ PyObject *raw = PyTuple_GET_ITEM(co->co_varnames, i);
+ PyObject *name = PyObject_Repr(raw);
+ if (name == NULL) {
+ Py_DECREF(missing_names);
+ return;
+ }
+ PyList_SET_ITEM(missing_names, j++, name);
+ }
+ }
+ assert(j == missing);
+ format_missing(tstate, kind, co, missing_names);
+ Py_DECREF(missing_names);
+}
+
+static void
+too_many_positional(PyThreadState *tstate, PyCodeObject *co,
+ Py_ssize_t given, Py_ssize_t defcount,
+ PyObject **fastlocals)
+{
+ int plural;
+ Py_ssize_t kwonly_given = 0;
+ Py_ssize_t i;
+ PyObject *sig, *kwonly_sig;
+ Py_ssize_t co_argcount = co->co_argcount;
+
+ assert((co->co_flags & CO_VARARGS) == 0);
+ /* Count missing keyword-only args. */
+ for (i = co_argcount; i < co_argcount + co->co_kwonlyargcount; i++) {
+ if (GETLOCAL(i) != NULL) {
+ kwonly_given++;
+ }
+ }
+ if (defcount) {
+ Py_ssize_t atleast = co_argcount - defcount;
+ plural = 1;
+ sig = PyUnicode_FromFormat("from %zd to %zd", atleast, co_argcount);
+ }
+ else {
+ plural = (co_argcount != 1);
+ sig = PyUnicode_FromFormat("%zd", co_argcount);
+ }
+ if (sig == NULL)
+ return;
+ if (kwonly_given) {
+ const char *format = " positional argument%s (and %zd keyword-only argument%s)";
+ kwonly_sig = PyUnicode_FromFormat(format,
+ given != 1 ? "s" : "",
+ kwonly_given,
+ kwonly_given != 1 ? "s" : "");
+ if (kwonly_sig == NULL) {
+ Py_DECREF(sig);
+ return;
+ }
+ }
+ else {
+ /* This will not fail. */
+ kwonly_sig = PyUnicode_FromString("");
+ assert(kwonly_sig != NULL);
+ }
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "%U() takes %U positional argument%s but %zd%U %s given",
+ co->co_name,
+ sig,
+ plural ? "s" : "",
+ given,
+ kwonly_sig,
+ given == 1 && !kwonly_given ? "was" : "were");
+ Py_DECREF(sig);
+ Py_DECREF(kwonly_sig);
+}
+
+static int
+positional_only_passed_as_keyword(PyThreadState *tstate, PyCodeObject *co,
+ Py_ssize_t kwcount, PyObject* const* kwnames)
+{
+ int posonly_conflicts = 0;
+ PyObject* posonly_names = PyList_New(0);
+
+ for(int k=0; k < co->co_posonlyargcount; k++){
+ PyObject* posonly_name = PyTuple_GET_ITEM(co->co_varnames, k);
+
+ for (int k2=0; k2<kwcount; k2++){
+ /* Compare the pointers first and fallback to PyObject_RichCompareBool*/
+ PyObject* kwname = kwnames[k2];
+ if (kwname == posonly_name){
+ if(PyList_Append(posonly_names, kwname) != 0) {
+ goto fail;
+ }
+ posonly_conflicts++;
+ continue;
+ }
+
+ int cmp = PyObject_RichCompareBool(posonly_name, kwname, Py_EQ);
+
+ if ( cmp > 0) {
+ if(PyList_Append(posonly_names, kwname) != 0) {
+ goto fail;
+ }
+ posonly_conflicts++;
+ } else if (cmp < 0) {
+ goto fail;
+ }
+
+ }
+ }
+ if (posonly_conflicts) {
+ PyObject* comma = PyUnicode_FromString(", ");
+ if (comma == NULL) {
+ goto fail;
+ }
+ PyObject* error_names = PyUnicode_Join(comma, posonly_names);
+ Py_DECREF(comma);
+ if (error_names == NULL) {
+ goto fail;
+ }
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "%U() got some positional-only arguments passed"
+ " as keyword arguments: '%U'",
+ co->co_name, error_names);
+ Py_DECREF(error_names);
+ goto fail;
+ }
+
+ Py_DECREF(posonly_names);
+ return 0;
+
+fail:
+ Py_XDECREF(posonly_names);
+ return 1;
+
+}
+
+/* This is gonna seem *real weird*, but if you put some other code between
+ PyEval_EvalFrame() and _PyEval_EvalFrameDefault() you will need to adjust
+ the test in the if statements in Misc/gdbinit (pystack and pystackv). */
+
+PyObject *
+_PyEval_EvalCode(PyThreadState *tstate,
+ PyObject *_co, PyObject *globals, PyObject *locals,
+ PyObject *const *args, Py_ssize_t argcount,
+ PyObject *const *kwnames, PyObject *const *kwargs,
+ Py_ssize_t kwcount, int kwstep,
+ PyObject *const *defs, Py_ssize_t defcount,
+ PyObject *kwdefs, PyObject *closure,
+ PyObject *name, PyObject *qualname)
+{
+ assert(is_tstate_valid(tstate));
+
+ PyCodeObject* co = (PyCodeObject*)_co;
+ PyFrameObject *f;
+ PyObject *retval = NULL;
+ PyObject **fastlocals, **freevars;
+ PyObject *x, *u;
+ const Py_ssize_t total_args = co->co_argcount + co->co_kwonlyargcount;
+ Py_ssize_t i, j, n;
+ PyObject *kwdict;
+
+ if (globals == NULL) {
+ _PyErr_SetString(tstate, PyExc_SystemError,
+ "PyEval_EvalCodeEx: NULL globals");
+ return NULL;
+ }
+
+ /* Create the frame */
+ f = _PyFrame_New_NoTrack(tstate, co, globals, locals);
+ if (f == NULL) {
+ return NULL;
+ }
+ fastlocals = f->f_localsplus;
+ freevars = f->f_localsplus + co->co_nlocals;
+
+ /* Create a dictionary for keyword parameters (**kwags) */
+ if (co->co_flags & CO_VARKEYWORDS) {
+ kwdict = PyDict_New();
+ if (kwdict == NULL)
+ goto fail;
+ i = total_args;
+ if (co->co_flags & CO_VARARGS) {
+ i++;
+ }
+ SETLOCAL(i, kwdict);
+ }
+ else {
+ kwdict = NULL;
+ }
+
+ /* Copy all positional arguments into local variables */
+ if (argcount > co->co_argcount) {
+ n = co->co_argcount;
+ }
+ else {
+ n = argcount;
+ }
+ for (j = 0; j < n; j++) {
+ x = args[j];
+ Py_INCREF(x);
+ SETLOCAL(j, x);
+ }
+
+ /* Pack other positional arguments into the *args argument */
+ if (co->co_flags & CO_VARARGS) {
+ u = _PyTuple_FromArray(args + n, argcount - n);
+ if (u == NULL) {
+ goto fail;
+ }
+ SETLOCAL(total_args, u);
+ }
+
+ /* Handle keyword arguments passed as two strided arrays */
+ kwcount *= kwstep;
+ for (i = 0; i < kwcount; i += kwstep) {
+ PyObject **co_varnames;
+ PyObject *keyword = kwnames[i];
+ PyObject *value = kwargs[i];
+ Py_ssize_t j;
+
+ if (keyword == NULL || !PyUnicode_Check(keyword)) {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "%U() keywords must be strings",
+ co->co_name);
+ goto fail;
+ }
+
+ /* Speed hack: do raw pointer compares. As names are
+ normally interned this should almost always hit. */
+ co_varnames = ((PyTupleObject *)(co->co_varnames))->ob_item;
+ for (j = co->co_posonlyargcount; j < total_args; j++) {
+ PyObject *name = co_varnames[j];
+ if (name == keyword) {
+ goto kw_found;
+ }
+ }
+
+ /* Slow fallback, just in case */
+ for (j = co->co_posonlyargcount; j < total_args; j++) {
+ PyObject *name = co_varnames[j];
+ int cmp = PyObject_RichCompareBool( keyword, name, Py_EQ);
+ if (cmp > 0) {
+ goto kw_found;
+ }
+ else if (cmp < 0) {
+ goto fail;
+ }
+ }
+
+ assert(j >= total_args);
+ if (kwdict == NULL) {
+
+ if (co->co_posonlyargcount
+ && positional_only_passed_as_keyword(tstate, co,
+ kwcount, kwnames))
+ {
+ goto fail;
+ }
+
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "%U() got an unexpected keyword argument '%S'",
+ co->co_name, keyword);
+ goto fail;
+ }
+
+ if (PyDict_SetItem(kwdict, keyword, value) == -1) {
+ goto fail;
+ }
+ continue;
+
+ kw_found:
+ if (GETLOCAL(j) != NULL) {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "%U() got multiple values for argument '%S'",
+ co->co_name, keyword);
+ goto fail;
+ }
+ Py_INCREF(value);
+ SETLOCAL(j, value);
+ }
+
+ /* Check the number of positional arguments */
+ if ((argcount > co->co_argcount) && !(co->co_flags & CO_VARARGS)) {
+ too_many_positional(tstate, co, argcount, defcount, fastlocals);
+ goto fail;
+ }
+
+ /* Add missing positional arguments (copy default values from defs) */
+ if (argcount < co->co_argcount) {
+ Py_ssize_t m = co->co_argcount - defcount;
+ Py_ssize_t missing = 0;
+ for (i = argcount; i < m; i++) {
+ if (GETLOCAL(i) == NULL) {
+ missing++;
+ }
+ }
+ if (missing) {
+ missing_arguments(tstate, co, missing, defcount, fastlocals);
+ goto fail;
+ }
+ if (n > m)
+ i = n - m;
+ else
+ i = 0;
+ for (; i < defcount; i++) {
+ if (GETLOCAL(m+i) == NULL) {
+ PyObject *def = defs[i];
+ Py_INCREF(def);
+ SETLOCAL(m+i, def);
+ }
+ }
+ }
+
+ /* Add missing keyword arguments (copy default values from kwdefs) */
+ if (co->co_kwonlyargcount > 0) {
+ Py_ssize_t missing = 0;
+ for (i = co->co_argcount; i < total_args; i++) {
+ PyObject *name;
+ if (GETLOCAL(i) != NULL)
+ continue;
+ name = PyTuple_GET_ITEM(co->co_varnames, i);
+ if (kwdefs != NULL) {
+ PyObject *def = PyDict_GetItemWithError(kwdefs, name);
+ if (def) {
+ Py_INCREF(def);
+ SETLOCAL(i, def);
+ continue;
+ }
+ else if (_PyErr_Occurred(tstate)) {
+ goto fail;
+ }
+ }
+ missing++;
+ }
+ if (missing) {
+ missing_arguments(tstate, co, missing, -1, fastlocals);
+ goto fail;
+ }
+ }
+
+ /* Allocate and initialize storage for cell vars, and copy free
+ vars into frame. */
+ for (i = 0; i < PyTuple_GET_SIZE(co->co_cellvars); ++i) {
+ PyObject *c;
+ Py_ssize_t arg;
+ /* Possibly account for the cell variable being an argument. */
+ if (co->co_cell2arg != NULL &&
+ (arg = co->co_cell2arg[i]) != CO_CELL_NOT_AN_ARG) {
+ c = PyCell_New(GETLOCAL(arg));
+ /* Clear the local copy. */
+ SETLOCAL(arg, NULL);
+ }
+ else {
+ c = PyCell_New(NULL);
+ }
+ if (c == NULL)
+ goto fail;
+ SETLOCAL(co->co_nlocals + i, c);
+ }
+
+ /* Copy closure variables to free variables */
+ for (i = 0; i < PyTuple_GET_SIZE(co->co_freevars); ++i) {
+ PyObject *o = PyTuple_GET_ITEM(closure, i);
+ Py_INCREF(o);
+ freevars[PyTuple_GET_SIZE(co->co_cellvars) + i] = o;
+ }
+
+ /* Handle generator/coroutine/asynchronous generator */
+ if (co->co_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) {
+ PyObject *gen;
+ int is_coro = co->co_flags & CO_COROUTINE;
+
+ /* Don't need to keep the reference to f_back, it will be set
+ * when the generator is resumed. */
+ Py_CLEAR(f->f_back);
+
+ /* Create a new generator that owns the ready to run frame
+ * and return that as the value. */
+ if (is_coro) {
+ gen = PyCoro_New(f, name, qualname);
+ } else if (co->co_flags & CO_ASYNC_GENERATOR) {
+ gen = PyAsyncGen_New(f, name, qualname);
+ } else {
+ gen = PyGen_NewWithQualName(f, name, qualname);
+ }
+ if (gen == NULL) {
+ return NULL;
+ }
+
+ _PyObject_GC_TRACK(f);
+
+ return gen;
+ }
+
+ retval = _PyEval_EvalFrame(tstate, f, 0);
+
+fail: /* Jump here from prelude on failure */
+
+ /* decref'ing the frame can cause __del__ methods to get invoked,
+ which can call back into Python. While we're done with the
+ current Python frame (f), the associated C stack is still in use,
+ so recursion_depth must be boosted for the duration.
+ */
+ if (Py_REFCNT(f) > 1) {
+ Py_DECREF(f);
+ _PyObject_GC_TRACK(f);
+ }
+ else {
+ ++tstate->recursion_depth;
+ Py_DECREF(f);
+ --tstate->recursion_depth;
+ }
+ return retval;
+}
+
+
+PyObject *
+_PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
+ PyObject *const *args, Py_ssize_t argcount,
+ PyObject *const *kwnames, PyObject *const *kwargs,
+ Py_ssize_t kwcount, int kwstep,
+ PyObject *const *defs, Py_ssize_t defcount,
+ PyObject *kwdefs, PyObject *closure,
+ PyObject *name, PyObject *qualname)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ return _PyEval_EvalCode(tstate, _co, globals, locals,
+ args, argcount,
+ kwnames, kwargs,
+ kwcount, kwstep,
+ defs, defcount,
+ kwdefs, closure,
+ name, qualname);
+}
+
+PyObject *
+PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals,
+ PyObject *const *args, int argcount,
+ PyObject *const *kws, int kwcount,
+ PyObject *const *defs, int defcount,
+ PyObject *kwdefs, PyObject *closure)
+{
+ return _PyEval_EvalCodeWithName(_co, globals, locals,
+ args, argcount,
+ kws, kws != NULL ? kws + 1 : NULL,
+ kwcount, 2,
+ defs, defcount,
+ kwdefs, closure,
+ NULL, NULL);
+}
+
+static PyObject *
+special_lookup(PyThreadState *tstate, PyObject *o, _Py_Identifier *id)
+{
+ PyObject *res;
+ res = _PyObject_LookupSpecial(o, id);
+ if (res == NULL && !_PyErr_Occurred(tstate)) {
+ _PyErr_SetObject(tstate, PyExc_AttributeError, _PyUnicode_FromId(id));
+ return NULL;
+ }
+ return res;
+}
+
+
+/* Logic for the raise statement (too complicated for inlining).
+ This *consumes* a reference count to each of its arguments. */
+static int
+do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause)
+{
+ PyObject *type = NULL, *value = NULL;
+
+ if (exc == NULL) {
+ /* Reraise */
+ _PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate);
+ PyObject *tb;
+ type = exc_info->exc_type;
+ value = exc_info->exc_value;
+ tb = exc_info->exc_traceback;
+ if (type == Py_None || type == NULL) {
+ _PyErr_SetString(tstate, PyExc_RuntimeError,
+ "No active exception to reraise");
+ return 0;
+ }
+ Py_XINCREF(type);
+ Py_XINCREF(value);
+ Py_XINCREF(tb);
+ _PyErr_Restore(tstate, type, value, tb);
+ return 1;
+ }
+
+ /* We support the following forms of raise:
+ raise
+ raise <instance>
+ raise <type> */
+
+ if (PyExceptionClass_Check(exc)) {
+ type = exc;
+ value = _PyObject_CallNoArg(exc);
+ if (value == NULL)
+ goto raise_error;
+ if (!PyExceptionInstance_Check(value)) {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "calling %R should have returned an instance of "
+ "BaseException, not %R",
+ type, Py_TYPE(value));
+ goto raise_error;
+ }
+ }
+ else if (PyExceptionInstance_Check(exc)) {
+ value = exc;
+ type = PyExceptionInstance_Class(exc);
+ Py_INCREF(type);
+ }
+ else {
+ /* Not something you can raise. You get an exception
+ anyway, just not what you specified :-) */
+ Py_DECREF(exc);
+ _PyErr_SetString(tstate, PyExc_TypeError,
+ "exceptions must derive from BaseException");
+ goto raise_error;
+ }
+
+ assert(type != NULL);
+ assert(value != NULL);
+
+ if (cause) {
+ PyObject *fixed_cause;
+ if (PyExceptionClass_Check(cause)) {
+ fixed_cause = _PyObject_CallNoArg(cause);
+ if (fixed_cause == NULL)
+ goto raise_error;
+ Py_DECREF(cause);
+ }
+ else if (PyExceptionInstance_Check(cause)) {
+ fixed_cause = cause;
+ }
+ else if (cause == Py_None) {
+ Py_DECREF(cause);
+ fixed_cause = NULL;
+ }
+ else {
+ _PyErr_SetString(tstate, PyExc_TypeError,
+ "exception causes must derive from "
+ "BaseException");
+ goto raise_error;
+ }
+ PyException_SetCause(value, fixed_cause);
+ }
+
+ _PyErr_SetObject(tstate, type, value);
+ /* _PyErr_SetObject incref's its arguments */
+ Py_DECREF(value);
+ Py_DECREF(type);
+ return 0;
+
+raise_error:
+ Py_XDECREF(value);
+ Py_XDECREF(type);
+ Py_XDECREF(cause);
+ return 0;
+}
+
+/* Iterate v argcnt times and store the results on the stack (via decreasing
+ sp). Return 1 for success, 0 if error.
+
+ If argcntafter == -1, do a simple unpack. If it is >= 0, do an unpack
+ with a variable target.
+*/
+
+static int
+unpack_iterable(PyThreadState *tstate, PyObject *v,
+ int argcnt, int argcntafter, PyObject **sp)
+{
+ int i = 0, j = 0;
+ Py_ssize_t ll = 0;
+ PyObject *it; /* iter(v) */
+ PyObject *w;
+ PyObject *l = NULL; /* variable list */
+
+ assert(v != NULL);
+
+ it = PyObject_GetIter(v);
+ if (it == NULL) {
+ if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) &&
+ Py_TYPE(v)->tp_iter == NULL && !PySequence_Check(v))
+ {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "cannot unpack non-iterable %.200s object",
+ Py_TYPE(v)->tp_name);
+ }
+ return 0;
+ }
+
+ for (; i < argcnt; i++) {
+ w = PyIter_Next(it);
+ if (w == NULL) {
+ /* Iterator done, via error or exhaustion. */
+ if (!_PyErr_Occurred(tstate)) {
+ if (argcntafter == -1) {
+ _PyErr_Format(tstate, PyExc_ValueError,
+ "not enough values to unpack "
+ "(expected %d, got %d)",
+ argcnt, i);
+ }
+ else {
+ _PyErr_Format(tstate, PyExc_ValueError,
+ "not enough values to unpack "
+ "(expected at least %d, got %d)",
+ argcnt + argcntafter, i);
+ }
+ }
+ goto Error;
+ }
+ *--sp = w;
+ }
+
+ if (argcntafter == -1) {
+ /* We better have exhausted the iterator now. */
+ w = PyIter_Next(it);
+ if (w == NULL) {
+ if (_PyErr_Occurred(tstate))
+ goto Error;
+ Py_DECREF(it);
+ return 1;
+ }
+ Py_DECREF(w);
+ _PyErr_Format(tstate, PyExc_ValueError,
+ "too many values to unpack (expected %d)",
+ argcnt);
+ goto Error;
+ }
+
+ l = PySequence_List(it);
+ if (l == NULL)
+ goto Error;
+ *--sp = l;
+ i++;
+
+ ll = PyList_GET_SIZE(l);
+ if (ll < argcntafter) {
+ _PyErr_Format(tstate, PyExc_ValueError,
+ "not enough values to unpack (expected at least %d, got %zd)",
+ argcnt + argcntafter, argcnt + ll);
+ goto Error;
+ }
+
+ /* Pop the "after-variable" args off the list. */
+ for (j = argcntafter; j > 0; j--, i++) {
+ *--sp = PyList_GET_ITEM(l, ll - j);
+ }
+ /* Resize the list. */
+ Py_SET_SIZE(l, ll - argcntafter);
+ Py_DECREF(it);
+ return 1;
+
+Error:
+ for (; i > 0; i--, sp++)
+ Py_DECREF(*sp);
+ Py_XDECREF(it);
+ return 0;
+}
+
+
+#ifdef LLTRACE
+static int
+prtrace(PyThreadState *tstate, PyObject *v, const char *str)
+{
+ printf("%s ", str);
+ PyObject *type, *value, *traceback;
+ PyErr_Fetch(&type, &value, &traceback);
+ if (PyObject_Print(v, stdout, 0) != 0) {
+ /* Don't know what else to do */
+ _PyErr_Clear(tstate);
+ }
+ printf("\n");
+ PyErr_Restore(type, value, traceback);
+ return 1;
+}
+#endif
+
+static void
+call_exc_trace(Py_tracefunc func, PyObject *self,
+ PyThreadState *tstate, PyFrameObject *f)
+{
+ PyObject *type, *value, *traceback, *orig_traceback, *arg;
+ int err;
+ _PyErr_Fetch(tstate, &type, &value, &orig_traceback);
+ if (value == NULL) {
+ value = Py_None;
+ Py_INCREF(value);
+ }
+ _PyErr_NormalizeException(tstate, &type, &value, &orig_traceback);
+ traceback = (orig_traceback != NULL) ? orig_traceback : Py_None;
+ arg = PyTuple_Pack(3, type, value, traceback);
+ if (arg == NULL) {
+ _PyErr_Restore(tstate, type, value, orig_traceback);
+ return;
+ }
+ err = call_trace(func, self, tstate, f, PyTrace_EXCEPTION, arg);
+ Py_DECREF(arg);
+ if (err == 0) {
+ _PyErr_Restore(tstate, type, value, orig_traceback);
+ }
+ else {
+ Py_XDECREF(type);
+ Py_XDECREF(value);
+ Py_XDECREF(orig_traceback);
+ }
+}
+
+static int
+call_trace_protected(Py_tracefunc func, PyObject *obj,
+ PyThreadState *tstate, PyFrameObject *frame,
+ int what, PyObject *arg)
+{
+ PyObject *type, *value, *traceback;
+ int err;
+ _PyErr_Fetch(tstate, &type, &value, &traceback);
+ err = call_trace(func, obj, tstate, frame, what, arg);
+ if (err == 0)
+ {
+ _PyErr_Restore(tstate, type, value, traceback);
+ return 0;
+ }
+ else {
+ Py_XDECREF(type);
+ Py_XDECREF(value);
+ Py_XDECREF(traceback);
+ return -1;
+ }
+}
+
+static int
+call_trace(Py_tracefunc func, PyObject *obj,
+ PyThreadState *tstate, PyFrameObject *frame,
+ int what, PyObject *arg)
+{
+ int result;
+ if (tstate->tracing)
+ return 0;
+ tstate->tracing++;
+ tstate->use_tracing = 0;
+ result = func(obj, frame, what, arg);
+ tstate->use_tracing = ((tstate->c_tracefunc != NULL)
+ || (tstate->c_profilefunc != NULL));
+ tstate->tracing--;
+ return result;
+}
+
+PyObject *
+_PyEval_CallTracing(PyObject *func, PyObject *args)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ int save_tracing = tstate->tracing;
+ int save_use_tracing = tstate->use_tracing;
+ PyObject *result;
+
+ tstate->tracing = 0;
+ tstate->use_tracing = ((tstate->c_tracefunc != NULL)
+ || (tstate->c_profilefunc != NULL));
+ result = PyObject_Call(func, args, NULL);
+ tstate->tracing = save_tracing;
+ tstate->use_tracing = save_use_tracing;
+ return result;
+}
+
+/* See Objects/lnotab_notes.txt for a description of how tracing works. */
+static int
+maybe_call_line_trace(Py_tracefunc func, PyObject *obj,
+ PyThreadState *tstate, PyFrameObject *frame,
+ int *instr_lb, int *instr_ub, int *instr_prev)
+{
+ int result = 0;
+ int line = frame->f_lineno;
+
+ /* If the last instruction executed isn't in the current
+ instruction window, reset the window.
+ */
+ if (frame->f_lasti < *instr_lb || frame->f_lasti >= *instr_ub) {
+ PyAddrPair bounds;
+ line = _PyCode_CheckLineNumber(frame->f_code, frame->f_lasti,
+ &bounds);
+ *instr_lb = bounds.ap_lower;
+ *instr_ub = bounds.ap_upper;
+ }
+ /* If the last instruction falls at the start of a line or if it
+ represents a jump backwards, update the frame's line number and
+ then call the trace function if we're tracing source lines.
+ */
+ if ((frame->f_lasti == *instr_lb || frame->f_lasti < *instr_prev)) {
+ frame->f_lineno = line;
+ if (frame->f_trace_lines) {
+ result = call_trace(func, obj, tstate, frame, PyTrace_LINE, Py_None);
+ }
+ }
+ /* Always emit an opcode event if we're tracing all opcodes. */
+ if (frame->f_trace_opcodes) {
+ result = call_trace(func, obj, tstate, frame, PyTrace_OPCODE, Py_None);
+ }
+ *instr_prev = frame->f_lasti;
+ return result;
+}
+
+int
+_PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
+{
+ assert(is_tstate_valid(tstate));
+ /* The caller must hold the GIL */
+ assert(PyGILState_Check());
+
+ /* Call _PySys_Audit() in the context of the current thread state,
+ even if tstate is not the current thread state. */
+ PyThreadState *current_tstate = _PyThreadState_GET();
+ if (_PySys_Audit(current_tstate, "sys.setprofile", NULL) < 0) {
+ return -1;
+ }
+
+ PyObject *profileobj = tstate->c_profileobj;
+
+ tstate->c_profilefunc = NULL;
+ tstate->c_profileobj = NULL;
+ /* Must make sure that tracing is not ignored if 'profileobj' is freed */
+ tstate->use_tracing = tstate->c_tracefunc != NULL;
+ Py_XDECREF(profileobj);
+
+ Py_XINCREF(arg);
+ tstate->c_profileobj = arg;
+ tstate->c_profilefunc = func;
+
+ /* Flag that tracing or profiling is turned on */
+ tstate->use_tracing = (func != NULL) || (tstate->c_tracefunc != NULL);
+ return 0;
+}
+
+void
+PyEval_SetProfile(Py_tracefunc func, PyObject *arg)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (_PyEval_SetProfile(tstate, func, arg) < 0) {
+ /* Log _PySys_Audit() error */
+ _PyErr_WriteUnraisableMsg("in PyEval_SetProfile", NULL);
+ }
+}
+
+int
+_PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
+{
+ assert(is_tstate_valid(tstate));
+ /* The caller must hold the GIL */
+ assert(PyGILState_Check());
+
+ /* Call _PySys_Audit() in the context of the current thread state,
+ even if tstate is not the current thread state. */
+ PyThreadState *current_tstate = _PyThreadState_GET();
+ if (_PySys_Audit(current_tstate, "sys.settrace", NULL) < 0) {
+ return -1;
+ }
+
+ struct _ceval_state *ceval2 = &tstate->interp->ceval;
+ PyObject *traceobj = tstate->c_traceobj;
+ ceval2->tracing_possible += (func != NULL) - (tstate->c_tracefunc != NULL);
+
+ tstate->c_tracefunc = NULL;
+ tstate->c_traceobj = NULL;
+ /* Must make sure that profiling is not ignored if 'traceobj' is freed */
+ tstate->use_tracing = (tstate->c_profilefunc != NULL);
+ Py_XDECREF(traceobj);
+
+ Py_XINCREF(arg);
+ tstate->c_traceobj = arg;
+ tstate->c_tracefunc = func;
+
+ /* Flag that tracing or profiling is turned on */
+ tstate->use_tracing = ((func != NULL)
+ || (tstate->c_profilefunc != NULL));
+
+ return 0;
+}
+
+void
+PyEval_SetTrace(Py_tracefunc func, PyObject *arg)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (_PyEval_SetTrace(tstate, func, arg) < 0) {
+ /* Log _PySys_Audit() error */
+ _PyErr_WriteUnraisableMsg("in PyEval_SetTrace", NULL);
+ }
+}
+
+
+void
+_PyEval_SetCoroutineOriginTrackingDepth(PyThreadState *tstate, int new_depth)
+{
+ assert(new_depth >= 0);
+ tstate->coroutine_origin_tracking_depth = new_depth;
+}
+
+int
+_PyEval_GetCoroutineOriginTrackingDepth(void)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ return tstate->coroutine_origin_tracking_depth;
+}
+
+int
+_PyEval_SetAsyncGenFirstiter(PyObject *firstiter)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+
+ if (_PySys_Audit(tstate, "sys.set_asyncgen_hook_firstiter", NULL) < 0) {
+ return -1;
+ }
+
+ Py_XINCREF(firstiter);
+ Py_XSETREF(tstate->async_gen_firstiter, firstiter);
+ return 0;
+}
+
+PyObject *
+_PyEval_GetAsyncGenFirstiter(void)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ return tstate->async_gen_firstiter;
+}
+
+int
+_PyEval_SetAsyncGenFinalizer(PyObject *finalizer)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+
+ if (_PySys_Audit(tstate, "sys.set_asyncgen_hook_finalizer", NULL) < 0) {
+ return -1;
+ }
+
+ Py_XINCREF(finalizer);
+ Py_XSETREF(tstate->async_gen_finalizer, finalizer);
+ return 0;
+}
+
+PyObject *
+_PyEval_GetAsyncGenFinalizer(void)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ return tstate->async_gen_finalizer;
+}
+
+PyFrameObject *
+PyEval_GetFrame(void)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ return tstate->frame;
+}
+
+PyObject *
+PyEval_GetBuiltins(void)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyFrameObject *current_frame = tstate->frame;
+ if (current_frame == NULL)
+ return tstate->interp->builtins;
+ else
+ return current_frame->f_builtins;
+}
+
+/* Convenience function to get a builtin from its name */
+PyObject *
+_PyEval_GetBuiltinId(_Py_Identifier *name)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyObject *attr = _PyDict_GetItemIdWithError(PyEval_GetBuiltins(), name);
+ if (attr) {
+ Py_INCREF(attr);
+ }
+ else if (!_PyErr_Occurred(tstate)) {
+ _PyErr_SetObject(tstate, PyExc_AttributeError, _PyUnicode_FromId(name));
+ }
+ return attr;
+}
+
+PyObject *
+PyEval_GetLocals(void)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyFrameObject *current_frame = tstate->frame;
+ if (current_frame == NULL) {
+ _PyErr_SetString(tstate, PyExc_SystemError, "frame does not exist");
+ return NULL;
+ }
+
+ if (PyFrame_FastToLocalsWithError(current_frame) < 0) {
+ return NULL;
+ }
+
+ assert(current_frame->f_locals != NULL);
+ return current_frame->f_locals;
+}
+
+PyObject *
+PyEval_GetGlobals(void)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyFrameObject *current_frame = tstate->frame;
+ if (current_frame == NULL) {
+ return NULL;
+ }
+
+ assert(current_frame->f_globals != NULL);
+ return current_frame->f_globals;
+}
+
+int
+PyEval_MergeCompilerFlags(PyCompilerFlags *cf)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyFrameObject *current_frame = tstate->frame;
+ int result = cf->cf_flags != 0;
+
+ if (current_frame != NULL) {
+ const int codeflags = current_frame->f_code->co_flags;
+ const int compilerflags = codeflags & PyCF_MASK;
+ if (compilerflags) {
+ result = 1;
+ cf->cf_flags |= compilerflags;
+ }
+#if 0 /* future keyword */
+ if (codeflags & CO_GENERATOR_ALLOWED) {
+ result = 1;
+ cf->cf_flags |= CO_GENERATOR_ALLOWED;
+ }
+#endif
+ }
+ return result;
+}
+
+
+const char *
+PyEval_GetFuncName(PyObject *func)
+{
+ if (PyMethod_Check(func))
+ return PyEval_GetFuncName(PyMethod_GET_FUNCTION(func));
+ else if (PyFunction_Check(func))
+ return PyUnicode_AsUTF8(((PyFunctionObject*)func)->func_name);
+ else if (PyCFunction_Check(func))
+ return ((PyCFunctionObject*)func)->m_ml->ml_name;
+ else
+ return Py_TYPE(func)->tp_name;
+}
+
+const char *
+PyEval_GetFuncDesc(PyObject *func)
+{
+ if (PyMethod_Check(func))
+ return "()";
+ else if (PyFunction_Check(func))
+ return "()";
+ else if (PyCFunction_Check(func))
+ return "()";
+ else
+ return " object";
+}
+
+#define C_TRACE(x, call) \
+if (tstate->use_tracing && tstate->c_profilefunc) { \
+ if (call_trace(tstate->c_profilefunc, tstate->c_profileobj, \
+ tstate, tstate->frame, \
+ PyTrace_C_CALL, func)) { \
+ x = NULL; \
+ } \
+ else { \
+ x = call; \
+ if (tstate->c_profilefunc != NULL) { \
+ if (x == NULL) { \
+ call_trace_protected(tstate->c_profilefunc, \
+ tstate->c_profileobj, \
+ tstate, tstate->frame, \
+ PyTrace_C_EXCEPTION, func); \
+ /* XXX should pass (type, value, tb) */ \
+ } else { \
+ if (call_trace(tstate->c_profilefunc, \
+ tstate->c_profileobj, \
+ tstate, tstate->frame, \
+ PyTrace_C_RETURN, func)) { \
+ Py_DECREF(x); \
+ x = NULL; \
+ } \
+ } \
+ } \
+ } \
+} else { \
+ x = call; \
+ }
+
+
+static PyObject *
+trace_call_function(PyThreadState *tstate,
+ PyObject *func,
+ PyObject **args, Py_ssize_t nargs,
+ PyObject *kwnames)
+{
+ PyObject *x;
+ if (PyCFunction_CheckExact(func) || PyCMethod_CheckExact(func)) {
+ C_TRACE(x, PyObject_Vectorcall(func, args, nargs, kwnames));
+ return x;
+ }
+ else if (Py_IS_TYPE(func, &PyMethodDescr_Type) && nargs > 0) {
+ /* We need to create a temporary bound method as argument
+ for profiling.
+
+ If nargs == 0, then this cannot work because we have no
+ "self". In any case, the call itself would raise
+ TypeError (foo needs an argument), so we just skip
+ profiling. */
+ PyObject *self = args[0];
+ func = Py_TYPE(func)->tp_descr_get(func, self, (PyObject*)Py_TYPE(self));
+ if (func == NULL) {
+ return NULL;
+ }
+ C_TRACE(x, PyObject_Vectorcall(func,
+ args+1, nargs-1,
+ kwnames));
+ Py_DECREF(func);
+ return x;
+ }
+ return PyObject_Vectorcall(func, args, nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames);
+}
+
+/* Issue #29227: Inline call_function() into _PyEval_EvalFrameDefault()
+ to reduce the stack consumption. */
+Py_LOCAL_INLINE(PyObject *) _Py_HOT_FUNCTION
+call_function(PyThreadState *tstate, PyObject ***pp_stack, Py_ssize_t oparg, PyObject *kwnames)
+{
+ PyObject **pfunc = (*pp_stack) - oparg - 1;
+ PyObject *func = *pfunc;
+ PyObject *x, *w;
+ Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames);
+ Py_ssize_t nargs = oparg - nkwargs;
+ PyObject **stack = (*pp_stack) - nargs - nkwargs;
+
+ if (tstate->use_tracing) {
+ x = trace_call_function(tstate, func, stack, nargs, kwnames);
+ }
+ else {
+ x = PyObject_Vectorcall(func, stack, nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames);
+ }
+
+ assert((x != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
+
+ /* Clear the stack of the function object. */
+ while ((*pp_stack) > pfunc) {
+ w = EXT_POP(*pp_stack);
+ Py_DECREF(w);
+ }
+
+ return x;
+}
+
+static PyObject *
+do_call_core(PyThreadState *tstate, PyObject *func, PyObject *callargs, PyObject *kwdict)
+{
+ PyObject *result;
+
+ if (PyCFunction_CheckExact(func) || PyCMethod_CheckExact(func)) {
+ C_TRACE(result, PyObject_Call(func, callargs, kwdict));
+ return result;
+ }
+ else if (Py_IS_TYPE(func, &PyMethodDescr_Type)) {
+ Py_ssize_t nargs = PyTuple_GET_SIZE(callargs);
+ if (nargs > 0 && tstate->use_tracing) {
+ /* We need to create a temporary bound method as argument
+ for profiling.
+
+ If nargs == 0, then this cannot work because we have no
+ "self". In any case, the call itself would raise
+ TypeError (foo needs an argument), so we just skip
+ profiling. */
+ PyObject *self = PyTuple_GET_ITEM(callargs, 0);
+ func = Py_TYPE(func)->tp_descr_get(func, self, (PyObject*)Py_TYPE(self));
+ if (func == NULL) {
+ return NULL;
+ }
+
+ C_TRACE(result, _PyObject_FastCallDictTstate(
+ tstate, func,
+ &_PyTuple_ITEMS(callargs)[1],
+ nargs - 1,
+ kwdict));
+ Py_DECREF(func);
+ return result;
+ }
+ }
+ return PyObject_Call(func, callargs, kwdict);
+}
+
+/* Extract a slice index from a PyLong or an object with the
+ nb_index slot defined, and store in *pi.
+ Silently reduce values larger than PY_SSIZE_T_MAX to PY_SSIZE_T_MAX,
+ and silently boost values less than PY_SSIZE_T_MIN to PY_SSIZE_T_MIN.
+ Return 0 on error, 1 on success.
+*/
+int
+_PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (v != Py_None) {
+ 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;
+ }
+ return 1;
+}
+
+int
+_PyEval_SliceIndexNotNone(PyObject *v, Py_ssize_t *pi)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ 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 "
+ "have an __index__ method");
+ return 0;
+ }
+ *pi = x;
+ return 1;
+}
+
+static PyObject *
+import_name(PyThreadState *tstate, PyFrameObject *f,
+ PyObject *name, PyObject *fromlist, PyObject *level)
+{
+ _Py_IDENTIFIER(__import__);
+ PyObject *import_func, *res;
+ PyObject* stack[5];
+
+ import_func = _PyDict_GetItemIdWithError(f->f_builtins, &PyId___import__);
+ if (import_func == NULL) {
+ if (!_PyErr_Occurred(tstate)) {
+ _PyErr_SetString(tstate, PyExc_ImportError, "__import__ not found");
+ }
+ return NULL;
+ }
+
+ /* Fast path for not overloaded __import__. */
+ if (import_func == tstate->interp->import_func) {
+ int ilevel = _PyLong_AsInt(level);
+ if (ilevel == -1 && _PyErr_Occurred(tstate)) {
+ return NULL;
+ }
+ res = PyImport_ImportModuleLevelObject(
+ name,
+ f->f_globals,
+ f->f_locals == NULL ? Py_None : f->f_locals,
+ fromlist,
+ ilevel);
+ return res;
+ }
+
+ Py_INCREF(import_func);
+
+ stack[0] = name;
+ stack[1] = f->f_globals;
+ stack[2] = f->f_locals == NULL ? Py_None : f->f_locals;
+ stack[3] = fromlist;
+ stack[4] = level;
+ res = _PyObject_FastCall(import_func, stack, 5);
+ Py_DECREF(import_func);
+ return res;
+}
+
+static PyObject *
+import_from(PyThreadState *tstate, PyObject *v, PyObject *name)
+{
+ PyObject *x;
+ PyObject *fullmodname, *pkgname, *pkgpath, *pkgname_or_unknown, *errmsg;
+
+ if (_PyObject_LookupAttr(v, name, &x) != 0) {
+ return x;
+ }
+ /* Issue #17636: in case this failed because of a circular relative
+ import, try to fallback on reading the module directly from
+ sys.modules. */
+ pkgname = _PyObject_GetAttrId(v, &PyId___name__);
+ if (pkgname == NULL) {
+ goto error;
+ }
+ if (!PyUnicode_Check(pkgname)) {
+ Py_CLEAR(pkgname);
+ goto error;
+ }
+ fullmodname = PyUnicode_FromFormat("%U.%U", pkgname, name);
+ if (fullmodname == NULL) {
+ Py_DECREF(pkgname);
+ return NULL;
+ }
+ x = PyImport_GetModule(fullmodname);
+ Py_DECREF(fullmodname);
+ if (x == NULL && !_PyErr_Occurred(tstate)) {
+ goto error;
+ }
+ Py_DECREF(pkgname);
+ return x;
+ error:
+ pkgpath = PyModule_GetFilenameObject(v);
+ if (pkgname == NULL) {
+ pkgname_or_unknown = PyUnicode_FromString("<unknown module name>");
+ if (pkgname_or_unknown == NULL) {
+ Py_XDECREF(pkgpath);
+ return NULL;
+ }
+ } else {
+ pkgname_or_unknown = pkgname;
+ }
+
+ if (pkgpath == NULL || !PyUnicode_Check(pkgpath)) {
+ _PyErr_Clear(tstate);
+ errmsg = PyUnicode_FromFormat(
+ "cannot import name %R from %R (unknown location)",
+ name, pkgname_or_unknown
+ );
+ /* NULL checks for errmsg and pkgname done by PyErr_SetImportError. */
+ PyErr_SetImportError(errmsg, pkgname, NULL);
+ }
+ else {
+ _Py_IDENTIFIER(__spec__);
+ PyObject *spec = _PyObject_GetAttrId(v, &PyId___spec__);
+ const char *fmt =
+ _PyModuleSpec_IsInitializing(spec) ?
+ "cannot import name %R from partially initialized module %R "
+ "(most likely due to a circular import) (%S)" :
+ "cannot import name %R from %R (%S)";
+ Py_XDECREF(spec);
+
+ errmsg = PyUnicode_FromFormat(fmt, name, pkgname_or_unknown, pkgpath);
+ /* NULL checks for errmsg and pkgname done by PyErr_SetImportError. */
+ PyErr_SetImportError(errmsg, pkgname, pkgpath);
+ }
+
+ Py_XDECREF(errmsg);
+ Py_XDECREF(pkgname_or_unknown);
+ Py_XDECREF(pkgpath);
+ return NULL;
+}
+
+static int
+import_all_from(PyThreadState *tstate, PyObject *locals, PyObject *v)
+{
+ _Py_IDENTIFIER(__all__);
+ _Py_IDENTIFIER(__dict__);
+ PyObject *all, *dict, *name, *value;
+ int skip_leading_underscores = 0;
+ int pos, err;
+
+ if (_PyObject_LookupAttrId(v, &PyId___all__, &all) < 0) {
+ return -1; /* Unexpected error */
+ }
+ if (all == NULL) {
+ if (_PyObject_LookupAttrId(v, &PyId___dict__, &dict) < 0) {
+ return -1;
+ }
+ if (dict == NULL) {
+ _PyErr_SetString(tstate, PyExc_ImportError,
+ "from-import-* object has no __dict__ and no __all__");
+ return -1;
+ }
+ all = PyMapping_Keys(dict);
+ Py_DECREF(dict);
+ if (all == NULL)
+ return -1;
+ skip_leading_underscores = 1;
+ }
+
+ for (pos = 0, err = 0; ; pos++) {
+ name = PySequence_GetItem(all, pos);
+ if (name == NULL) {
+ if (!_PyErr_ExceptionMatches(tstate, PyExc_IndexError)) {
+ err = -1;
+ }
+ else {
+ _PyErr_Clear(tstate);
+ }
+ break;
+ }
+ if (!PyUnicode_Check(name)) {
+ PyObject *modname = _PyObject_GetAttrId(v, &PyId___name__);
+ if (modname == NULL) {
+ Py_DECREF(name);
+ err = -1;
+ break;
+ }
+ if (!PyUnicode_Check(modname)) {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "module __name__ must be a string, not %.100s",
+ Py_TYPE(modname)->tp_name);
+ }
+ else {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "%s in %U.%s must be str, not %.100s",
+ skip_leading_underscores ? "Key" : "Item",
+ modname,
+ skip_leading_underscores ? "__dict__" : "__all__",
+ Py_TYPE(name)->tp_name);
+ }
+ Py_DECREF(modname);
+ Py_DECREF(name);
+ err = -1;
+ break;
+ }
+ if (skip_leading_underscores) {
+ if (PyUnicode_READY(name) == -1) {
+ Py_DECREF(name);
+ err = -1;
+ break;
+ }
+ if (PyUnicode_READ_CHAR(name, 0) == '_') {
+ Py_DECREF(name);
+ continue;
+ }
+ }
+ value = PyObject_GetAttr(v, name);
+ if (value == NULL)
+ err = -1;
+ else if (PyDict_CheckExact(locals))
+ err = PyDict_SetItem(locals, name, value);
+ else
+ err = PyObject_SetItem(locals, name, value);
+ Py_DECREF(name);
+ Py_XDECREF(value);
+ if (err != 0)
+ break;
+ }
+ Py_DECREF(all);
+ return err;
+}
+
+static int
+check_args_iterable(PyThreadState *tstate, PyObject *func, PyObject *args)
+{
+ if (Py_TYPE(args)->tp_iter == NULL && !PySequence_Check(args)) {
+ /* check_args_iterable() may be called with a live exception:
+ * clear it to prevent calling _PyObject_FunctionStr() with an
+ * exception set. */
+ _PyErr_Clear(tstate);
+ PyObject *funcstr = _PyObject_FunctionStr(func);
+ if (funcstr != NULL) {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "%U argument after * must be an iterable, not %.200s",
+ funcstr, Py_TYPE(args)->tp_name);
+ Py_DECREF(funcstr);
+ }
+ return -1;
+ }
+ return 0;
+}
+
+static void
+format_kwargs_error(PyThreadState *tstate, PyObject *func, PyObject *kwargs)
+{
+ /* _PyDict_MergeEx raises attribute
+ * error (percolated from an attempt
+ * to get 'keys' attribute) instead of
+ * a type error if its second argument
+ * is not a mapping.
+ */
+ if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) {
+ _PyErr_Clear(tstate);
+ PyObject *funcstr = _PyObject_FunctionStr(func);
+ if (funcstr != NULL) {
+ _PyErr_Format(
+ tstate, PyExc_TypeError,
+ "%U argument after ** must be a mapping, not %.200s",
+ funcstr, Py_TYPE(kwargs)->tp_name);
+ Py_DECREF(funcstr);
+ }
+ }
+ else if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
+ PyObject *exc, *val, *tb;
+ _PyErr_Fetch(tstate, &exc, &val, &tb);
+ if (val && PyTuple_Check(val) && PyTuple_GET_SIZE(val) == 1) {
+ _PyErr_Clear(tstate);
+ PyObject *funcstr = _PyObject_FunctionStr(func);
+ if (funcstr != NULL) {
+ PyObject *key = PyTuple_GET_ITEM(val, 0);
+ _PyErr_Format(
+ tstate, PyExc_TypeError,
+ "%U got multiple values for keyword argument '%S'",
+ funcstr, key);
+ Py_DECREF(funcstr);
+ }
+ Py_XDECREF(exc);
+ Py_XDECREF(val);
+ Py_XDECREF(tb);
+ }
+ else {
+ _PyErr_Restore(tstate, exc, val, tb);
+ }
+ }
+}
+
+static void
+format_exc_check_arg(PyThreadState *tstate, PyObject *exc,
+ const char *format_str, PyObject *obj)
+{
+ const char *obj_str;
+
+ if (!obj)
+ return;
+
+ obj_str = PyUnicode_AsUTF8(obj);
+ if (!obj_str)
+ return;
+
+ _PyErr_Format(tstate, exc, format_str, obj_str);
+}
+
+static void
+format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg)
+{
+ PyObject *name;
+ /* Don't stomp existing exception */
+ if (_PyErr_Occurred(tstate))
+ return;
+ if (oparg < PyTuple_GET_SIZE(co->co_cellvars)) {
+ name = PyTuple_GET_ITEM(co->co_cellvars,
+ oparg);
+ format_exc_check_arg(tstate,
+ PyExc_UnboundLocalError,
+ UNBOUNDLOCAL_ERROR_MSG,
+ name);
+ } else {
+ name = PyTuple_GET_ITEM(co->co_freevars, oparg -
+ PyTuple_GET_SIZE(co->co_cellvars));
+ format_exc_check_arg(tstate, PyExc_NameError,
+ UNBOUNDFREE_ERROR_MSG, name);
+ }
+}
+
+static void
+format_awaitable_error(PyThreadState *tstate, PyTypeObject *type, int prevprevopcode, int prevopcode)
+{
+ if (type->tp_as_async == NULL || type->tp_as_async->am_await == NULL) {
+ if (prevopcode == BEFORE_ASYNC_WITH) {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "'async with' received an object from __aenter__ "
+ "that does not implement __await__: %.100s",
+ type->tp_name);
+ }
+ else if (prevopcode == WITH_EXCEPT_START || (prevopcode == CALL_FUNCTION && prevprevopcode == DUP_TOP)) {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "'async with' received an object from __aexit__ "
+ "that does not implement __await__: %.100s",
+ type->tp_name);
+ }
+ }
+}
+
+static PyObject *
+unicode_concatenate(PyThreadState *tstate, PyObject *v, PyObject *w,
+ PyFrameObject *f, const _Py_CODEUNIT *next_instr)
+{
+ PyObject *res;
+ if (Py_REFCNT(v) == 2) {
+ /* In the common case, there are 2 references to the value
+ * stored in 'variable' when the += is performed: one on the
+ * value stack (in 'v') and one still stored in the
+ * 'variable'. We try to delete the variable now to reduce
+ * the refcnt to 1.
+ */
+ int opcode, oparg;
+ NEXTOPARG();
+ switch (opcode) {
+ case STORE_FAST:
+ {
+ PyObject **fastlocals = f->f_localsplus;
+ if (GETLOCAL(oparg) == v)
+ SETLOCAL(oparg, NULL);
+ break;
+ }
+ case STORE_DEREF:
+ {
+ PyObject **freevars = (f->f_localsplus +
+ f->f_code->co_nlocals);
+ PyObject *c = freevars[oparg];
+ if (PyCell_GET(c) == v) {
+ PyCell_SET(c, NULL);
+ Py_DECREF(v);
+ }
+ break;
+ }
+ case STORE_NAME:
+ {
+ PyObject *names = f->f_code->co_names;
+ PyObject *name = GETITEM(names, oparg);
+ PyObject *locals = f->f_locals;
+ if (locals && PyDict_CheckExact(locals)) {
+ PyObject *w = PyDict_GetItemWithError(locals, name);
+ if ((w == v && PyDict_DelItem(locals, name) != 0) ||
+ (w == NULL && _PyErr_Occurred(tstate)))
+ {
+ Py_DECREF(v);
+ return NULL;
+ }
+ }
+ break;
+ }
+ }
+ }
+ res = v;
+ PyUnicode_Append(&res, w);
+ return res;
+}
+
+#ifdef DYNAMIC_EXECUTION_PROFILE
+
+static PyObject *
+getarray(long a[256])
+{
+ int i;
+ PyObject *l = PyList_New(256);
+ if (l == NULL) return NULL;
+ for (i = 0; i < 256; i++) {
+ PyObject *x = PyLong_FromLong(a[i]);
+ if (x == NULL) {
+ Py_DECREF(l);
+ return NULL;
+ }
+ PyList_SET_ITEM(l, i, x);
+ }
+ for (i = 0; i < 256; i++)
+ a[i] = 0;
+ return l;
+}
+
+PyObject *
+_Py_GetDXProfile(PyObject *self, PyObject *args)
+{
+#ifndef DXPAIRS
+ return getarray(dxp);
+#else
+ int i;
+ PyObject *l = PyList_New(257);
+ if (l == NULL) return NULL;
+ for (i = 0; i < 257; i++) {
+ PyObject *x = getarray(dxpairs[i]);
+ if (x == NULL) {
+ Py_DECREF(l);
+ return NULL;
+ }
+ PyList_SET_ITEM(l, i, x);
+ }
+ return l;
+#endif
+}
+
+#endif
+
+Py_ssize_t
+_PyEval_RequestCodeExtraIndex(freefunc free)
+{
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ Py_ssize_t new_index;
+
+ if (interp->co_extra_user_count == MAX_CO_EXTRA_USERS - 1) {
+ return -1;
+ }
+ new_index = interp->co_extra_user_count++;
+ interp->co_extra_freefuncs[new_index] = free;
+ return new_index;
+}
+
+static void
+dtrace_function_entry(PyFrameObject *f)
+{
+ const char *filename;
+ const char *funcname;
+ int lineno;
+
+ PyCodeObject *code = f->f_code;
+ filename = PyUnicode_AsUTF8(code->co_filename);
+ funcname = PyUnicode_AsUTF8(code->co_name);
+ lineno = PyCode_Addr2Line(code, f->f_lasti);
+
+ PyDTrace_FUNCTION_ENTRY(filename, funcname, lineno);
+}
+
+static void
+dtrace_function_return(PyFrameObject *f)
+{
+ const char *filename;
+ const char *funcname;
+ int lineno;
+
+ PyCodeObject *code = f->f_code;
+ filename = PyUnicode_AsUTF8(code->co_filename);
+ funcname = PyUnicode_AsUTF8(code->co_name);
+ lineno = PyCode_Addr2Line(code, f->f_lasti);
+
+ PyDTrace_FUNCTION_RETURN(filename, funcname, lineno);
+}
+
+/* DTrace equivalent of maybe_call_line_trace. */
+static void
+maybe_dtrace_line(PyFrameObject *frame,
+ int *instr_lb, int *instr_ub, int *instr_prev)
+{
+ int line = frame->f_lineno;
+ const char *co_filename, *co_name;
+
+ /* If the last instruction executed isn't in the current
+ instruction window, reset the window.
+ */
+ if (frame->f_lasti < *instr_lb || frame->f_lasti >= *instr_ub) {
+ PyAddrPair bounds;
+ line = _PyCode_CheckLineNumber(frame->f_code, frame->f_lasti,
+ &bounds);
+ *instr_lb = bounds.ap_lower;
+ *instr_ub = bounds.ap_upper;
+ }
+ /* If the last instruction falls at the start of a line or if
+ it represents a jump backwards, update the frame's line
+ number and call the trace function. */
+ if (frame->f_lasti == *instr_lb || frame->f_lasti < *instr_prev) {
+ frame->f_lineno = line;
+ co_filename = PyUnicode_AsUTF8(frame->f_code->co_filename);
+ if (!co_filename)
+ co_filename = "?";
+ co_name = PyUnicode_AsUTF8(frame->f_code->co_name);
+ if (!co_name)
+ co_name = "?";
+ PyDTrace_LINE(co_filename, co_name, line);
+ }
+ *instr_prev = frame->f_lasti;
+}
+
+
+/* Implement Py_EnterRecursiveCall() and Py_LeaveRecursiveCall() as functions
+ for the limited API. */
+
+#undef Py_EnterRecursiveCall
+
+int Py_EnterRecursiveCall(const char *where)
+{
+ return _Py_EnterRecursiveCall_inline(where);
+}
+
+#undef Py_LeaveRecursiveCall
+
+void Py_LeaveRecursiveCall(void)
+{
+ _Py_LeaveRecursiveCall_inline();
+}
diff --git a/contrib/tools/python3/src/Python/ceval_gil.h b/contrib/tools/python3/src/Python/ceval_gil.h
new file mode 100644
index 00000000000..3510675a69b
--- /dev/null
+++ b/contrib/tools/python3/src/Python/ceval_gil.h
@@ -0,0 +1,331 @@
+/*
+ * Implementation of the Global Interpreter Lock (GIL).
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+
+#include "pycore_atomic.h"
+
+
+/*
+ Notes about the implementation:
+
+ - The GIL is just a boolean variable (locked) whose access is protected
+ by a mutex (gil_mutex), and whose changes are signalled by a condition
+ variable (gil_cond). gil_mutex is taken for short periods of time,
+ and therefore mostly uncontended.
+
+ - In the GIL-holding thread, the main loop (PyEval_EvalFrameEx) must be
+ able to release the GIL on demand by another thread. A volatile boolean
+ variable (gil_drop_request) is used for that purpose, which is checked
+ at every turn of the eval loop. That variable is set after a wait of
+ `interval` microseconds on `gil_cond` has timed out.
+
+ [Actually, another volatile boolean variable (eval_breaker) is used
+ which ORs several conditions into one. Volatile booleans are
+ sufficient as inter-thread signalling means since Python is run
+ on cache-coherent architectures only.]
+
+ - A thread wanting to take the GIL will first let pass a given amount of
+ time (`interval` microseconds) before setting gil_drop_request. This
+ encourages a defined switching period, but doesn't enforce it since
+ opcodes can take an arbitrary time to execute.
+
+ The `interval` value is available for the user to read and modify
+ using the Python API `sys.{get,set}switchinterval()`.
+
+ - When a thread releases the GIL and gil_drop_request is set, that thread
+ ensures that another GIL-awaiting thread gets scheduled.
+ It does so by waiting on a condition variable (switch_cond) until
+ the value of last_holder is changed to something else than its
+ own thread state pointer, indicating that another thread was able to
+ take the GIL.
+
+ This is meant to prohibit the latency-adverse behaviour on multi-core
+ machines where one thread would speculatively release the GIL, but still
+ run and end up being the first to re-acquire it, making the "timeslices"
+ much longer than expected.
+ (Note: this mechanism is enabled with FORCE_SWITCHING above)
+*/
+
+#include "condvar.h"
+
+#define MUTEX_INIT(mut) \
+ if (PyMUTEX_INIT(&(mut))) { \
+ Py_FatalError("PyMUTEX_INIT(" #mut ") failed"); };
+#define MUTEX_FINI(mut) \
+ if (PyMUTEX_FINI(&(mut))) { \
+ Py_FatalError("PyMUTEX_FINI(" #mut ") failed"); };
+#define MUTEX_LOCK(mut) \
+ if (PyMUTEX_LOCK(&(mut))) { \
+ Py_FatalError("PyMUTEX_LOCK(" #mut ") failed"); };
+#define MUTEX_UNLOCK(mut) \
+ if (PyMUTEX_UNLOCK(&(mut))) { \
+ Py_FatalError("PyMUTEX_UNLOCK(" #mut ") failed"); };
+
+#define COND_INIT(cond) \
+ if (PyCOND_INIT(&(cond))) { \
+ Py_FatalError("PyCOND_INIT(" #cond ") failed"); };
+#define COND_FINI(cond) \
+ if (PyCOND_FINI(&(cond))) { \
+ Py_FatalError("PyCOND_FINI(" #cond ") failed"); };
+#define COND_SIGNAL(cond) \
+ if (PyCOND_SIGNAL(&(cond))) { \
+ Py_FatalError("PyCOND_SIGNAL(" #cond ") failed"); };
+#define COND_WAIT(cond, mut) \
+ if (PyCOND_WAIT(&(cond), &(mut))) { \
+ Py_FatalError("PyCOND_WAIT(" #cond ") failed"); };
+#define COND_TIMED_WAIT(cond, mut, microseconds, timeout_result) \
+ { \
+ int r = PyCOND_TIMEDWAIT(&(cond), &(mut), (microseconds)); \
+ if (r < 0) \
+ Py_FatalError("PyCOND_WAIT(" #cond ") failed"); \
+ if (r) /* 1 == timeout, 2 == impl. can't say, so assume timeout */ \
+ timeout_result = 1; \
+ else \
+ timeout_result = 0; \
+ } \
+
+
+#define DEFAULT_INTERVAL 5000
+
+static void _gil_initialize(struct _gil_runtime_state *gil)
+{
+ _Py_atomic_int uninitialized = {-1};
+ gil->locked = uninitialized;
+ gil->interval = DEFAULT_INTERVAL;
+}
+
+static int gil_created(struct _gil_runtime_state *gil)
+{
+ return (_Py_atomic_load_explicit(&gil->locked, _Py_memory_order_acquire) >= 0);
+}
+
+static void create_gil(struct _gil_runtime_state *gil)
+{
+ MUTEX_INIT(gil->mutex);
+#ifdef FORCE_SWITCHING
+ MUTEX_INIT(gil->switch_mutex);
+#endif
+ COND_INIT(gil->cond);
+#ifdef FORCE_SWITCHING
+ COND_INIT(gil->switch_cond);
+#endif
+ _Py_atomic_store_relaxed(&gil->last_holder, 0);
+ _Py_ANNOTATE_RWLOCK_CREATE(&gil->locked);
+ _Py_atomic_store_explicit(&gil->locked, 0, _Py_memory_order_release);
+}
+
+static void destroy_gil(struct _gil_runtime_state *gil)
+{
+ /* some pthread-like implementations tie the mutex to the cond
+ * and must have the cond destroyed first.
+ */
+ COND_FINI(gil->cond);
+ MUTEX_FINI(gil->mutex);
+#ifdef FORCE_SWITCHING
+ COND_FINI(gil->switch_cond);
+ MUTEX_FINI(gil->switch_mutex);
+#endif
+ _Py_atomic_store_explicit(&gil->locked, -1,
+ _Py_memory_order_release);
+ _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked);
+}
+
+static void recreate_gil(struct _gil_runtime_state *gil)
+{
+ _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked);
+ /* XXX should we destroy the old OS resources here? */
+ create_gil(gil);
+}
+
+static void
+drop_gil(struct _ceval_runtime_state *ceval, struct _ceval_state *ceval2,
+ PyThreadState *tstate)
+{
+ struct _gil_runtime_state *gil = &ceval->gil;
+ if (!_Py_atomic_load_relaxed(&gil->locked)) {
+ Py_FatalError("drop_gil: GIL is not locked");
+ }
+
+ /* tstate is allowed to be NULL (early interpreter init) */
+ if (tstate != NULL) {
+ /* Sub-interpreter support: threads might have been switched
+ under our feet using PyThreadState_Swap(). Fix the GIL last
+ holder variable so that our heuristics work. */
+ _Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate);
+ }
+
+ MUTEX_LOCK(gil->mutex);
+ _Py_ANNOTATE_RWLOCK_RELEASED(&gil->locked, /*is_write=*/1);
+ _Py_atomic_store_relaxed(&gil->locked, 0);
+ COND_SIGNAL(gil->cond);
+ MUTEX_UNLOCK(gil->mutex);
+
+#ifdef FORCE_SWITCHING
+ if (_Py_atomic_load_relaxed(&ceval2->gil_drop_request) && tstate != NULL) {
+ MUTEX_LOCK(gil->switch_mutex);
+ /* Not switched yet => wait */
+ if (((PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) == tstate)
+ {
+ assert(is_tstate_valid(tstate));
+ RESET_GIL_DROP_REQUEST(tstate->interp);
+ /* NOTE: if COND_WAIT does not atomically start waiting when
+ releasing the mutex, another thread can run through, take
+ the GIL and drop it again, and reset the condition
+ before we even had a chance to wait for it. */
+ COND_WAIT(gil->switch_cond, gil->switch_mutex);
+ }
+ MUTEX_UNLOCK(gil->switch_mutex);
+ }
+#endif
+}
+
+
+/* Check if a Python thread must exit immediately, rather than taking the GIL
+ if Py_Finalize() has been called.
+
+ When this function is called by a daemon thread after Py_Finalize() has been
+ called, the GIL does no longer exist.
+
+ tstate must be non-NULL. */
+static inline int
+tstate_must_exit(PyThreadState *tstate)
+{
+ /* bpo-39877: Access _PyRuntime directly rather than using
+ tstate->interp->runtime to support calls from Python daemon threads.
+ After Py_Finalize() has been called, tstate can be a dangling pointer:
+ point to PyThreadState freed memory. */
+ PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(&_PyRuntime);
+ return (finalizing != NULL && finalizing != tstate);
+}
+
+
+/* Take the GIL.
+
+ The function saves errno at entry and restores its value at exit.
+
+ tstate must be non-NULL. */
+static void
+take_gil(PyThreadState *tstate)
+{
+ int err = errno;
+
+ assert(tstate != NULL);
+
+ if (tstate_must_exit(tstate)) {
+ /* bpo-39877: If Py_Finalize() has been called and tstate is not the
+ thread which called Py_Finalize(), exit immediately the thread.
+
+ This code path can be reached by a daemon thread after Py_Finalize()
+ completes. In this case, tstate is a dangling pointer: points to
+ PyThreadState freed memory. */
+ PyThread_exit_thread();
+ }
+
+ assert(is_tstate_valid(tstate));
+ PyInterpreterState *interp = tstate->interp;
+ struct _ceval_runtime_state *ceval = &interp->runtime->ceval;
+ struct _ceval_state *ceval2 = &interp->ceval;
+ struct _gil_runtime_state *gil = &ceval->gil;
+
+ /* Check that _PyEval_InitThreads() was called to create the lock */
+ assert(gil_created(gil));
+
+ MUTEX_LOCK(gil->mutex);
+
+ if (!_Py_atomic_load_relaxed(&gil->locked)) {
+ goto _ready;
+ }
+
+ while (_Py_atomic_load_relaxed(&gil->locked)) {
+ unsigned long saved_switchnum = gil->switch_number;
+
+ unsigned long interval = (gil->interval >= 1 ? gil->interval : 1);
+ int timed_out = 0;
+ COND_TIMED_WAIT(gil->cond, gil->mutex, interval, timed_out);
+
+ /* If we timed out and no switch occurred in the meantime, it is time
+ to ask the GIL-holding thread to drop it. */
+ if (timed_out &&
+ _Py_atomic_load_relaxed(&gil->locked) &&
+ gil->switch_number == saved_switchnum)
+ {
+ if (tstate_must_exit(tstate)) {
+ MUTEX_UNLOCK(gil->mutex);
+ PyThread_exit_thread();
+ }
+ assert(is_tstate_valid(tstate));
+
+ SET_GIL_DROP_REQUEST(interp);
+ }
+ }
+
+_ready:
+#ifdef FORCE_SWITCHING
+ /* This mutex must be taken before modifying gil->last_holder:
+ see drop_gil(). */
+ MUTEX_LOCK(gil->switch_mutex);
+#endif
+ /* We now hold the GIL */
+ _Py_atomic_store_relaxed(&gil->locked, 1);
+ _Py_ANNOTATE_RWLOCK_ACQUIRED(&gil->locked, /*is_write=*/1);
+
+ if (tstate != (PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) {
+ _Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate);
+ ++gil->switch_number;
+ }
+
+#ifdef FORCE_SWITCHING
+ COND_SIGNAL(gil->switch_cond);
+ MUTEX_UNLOCK(gil->switch_mutex);
+#endif
+
+ if (tstate_must_exit(tstate)) {
+ /* bpo-36475: If Py_Finalize() has been called and tstate is not
+ the thread which called Py_Finalize(), exit immediately the
+ thread.
+
+ This code path can be reached by a daemon thread which was waiting
+ in take_gil() while the main thread called
+ wait_for_thread_shutdown() from Py_Finalize(). */
+ MUTEX_UNLOCK(gil->mutex);
+ drop_gil(ceval, ceval2, tstate);
+ PyThread_exit_thread();
+ }
+ assert(is_tstate_valid(tstate));
+
+ if (_Py_atomic_load_relaxed(&ceval2->gil_drop_request)) {
+ RESET_GIL_DROP_REQUEST(interp);
+ }
+ else {
+ /* bpo-40010: eval_breaker should be recomputed to be set to 1 if there
+ is a pending signal: signal received by another thread which cannot
+ handle signals.
+
+ Note: RESET_GIL_DROP_REQUEST() calls COMPUTE_EVAL_BREAKER(). */
+ COMPUTE_EVAL_BREAKER(interp, ceval, ceval2);
+ }
+
+ /* Don't access tstate if the thread must exit */
+ if (tstate->async_exc != NULL) {
+ _PyEval_SignalAsyncExc(tstate);
+ }
+
+ MUTEX_UNLOCK(gil->mutex);
+
+ errno = err;
+}
+
+void _PyEval_SetSwitchInterval(unsigned long microseconds)
+{
+ struct _gil_runtime_state *gil = &_PyRuntime.ceval.gil;
+ gil->interval = microseconds;
+}
+
+unsigned long _PyEval_GetSwitchInterval()
+{
+ struct _gil_runtime_state *gil = &_PyRuntime.ceval.gil;
+ return gil->interval;
+}
diff --git a/contrib/tools/python3/src/Python/clinic/_warnings.c.h b/contrib/tools/python3/src/Python/clinic/_warnings.c.h
new file mode 100644
index 00000000000..67ab0e3d9de
--- /dev/null
+++ b/contrib/tools/python3/src/Python/clinic/_warnings.c.h
@@ -0,0 +1,74 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+PyDoc_STRVAR(warnings_warn__doc__,
+"warn($module, /, message, category=None, stacklevel=1, source=None)\n"
+"--\n"
+"\n"
+"Issue a warning, or maybe ignore it or raise an exception.");
+
+#define WARNINGS_WARN_METHODDEF \
+ {"warn", (PyCFunction)(void(*)(void))warnings_warn, METH_FASTCALL|METH_KEYWORDS, warnings_warn__doc__},
+
+static PyObject *
+warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category,
+ Py_ssize_t stacklevel, PyObject *source);
+
+static PyObject *
+warnings_warn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"message", "category", "stacklevel", "source", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "warn", 0};
+ PyObject *argsbuf[4];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+ PyObject *message;
+ PyObject *category = Py_None;
+ Py_ssize_t stacklevel = 1;
+ PyObject *source = Py_None;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 4, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ message = args[0];
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ if (args[1]) {
+ category = args[1];
+ if (!--noptargs) {
+ goto skip_optional_pos;
+ }
+ }
+ if (args[2]) {
+ if (PyFloat_Check(args[2])) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument expected, got float" );
+ goto exit;
+ }
+ {
+ Py_ssize_t ival = -1;
+ PyObject *iobj = PyNumber_Index(args[2]);
+ if (iobj != NULL) {
+ ival = PyLong_AsSsize_t(iobj);
+ Py_DECREF(iobj);
+ }
+ if (ival == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+ stacklevel = ival;
+ }
+ if (!--noptargs) {
+ goto skip_optional_pos;
+ }
+ }
+ source = args[3];
+skip_optional_pos:
+ return_value = warnings_warn_impl(module, message, category, stacklevel, source);
+
+exit:
+ return return_value;
+}
+/*[clinic end generated code: output=b7bb54c73b5433ec input=a9049054013a1b77]*/
diff --git a/contrib/tools/python3/src/Python/clinic/bltinmodule.c.h b/contrib/tools/python3/src/Python/clinic/bltinmodule.c.h
new file mode 100644
index 00000000000..d15af1f7f37
--- /dev/null
+++ b/contrib/tools/python3/src/Python/clinic/bltinmodule.c.h
@@ -0,0 +1,858 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+PyDoc_STRVAR(builtin_abs__doc__,
+"abs($module, x, /)\n"
+"--\n"
+"\n"
+"Return the absolute value of the argument.");
+
+#define BUILTIN_ABS_METHODDEF \
+ {"abs", (PyCFunction)builtin_abs, METH_O, builtin_abs__doc__},
+
+PyDoc_STRVAR(builtin_all__doc__,
+"all($module, iterable, /)\n"
+"--\n"
+"\n"
+"Return True if bool(x) is True for all values x in the iterable.\n"
+"\n"
+"If the iterable is empty, return True.");
+
+#define BUILTIN_ALL_METHODDEF \
+ {"all", (PyCFunction)builtin_all, METH_O, builtin_all__doc__},
+
+PyDoc_STRVAR(builtin_any__doc__,
+"any($module, iterable, /)\n"
+"--\n"
+"\n"
+"Return True if bool(x) is True for any x in the iterable.\n"
+"\n"
+"If the iterable is empty, return False.");
+
+#define BUILTIN_ANY_METHODDEF \
+ {"any", (PyCFunction)builtin_any, METH_O, builtin_any__doc__},
+
+PyDoc_STRVAR(builtin_ascii__doc__,
+"ascii($module, obj, /)\n"
+"--\n"
+"\n"
+"Return an ASCII-only representation of an object.\n"
+"\n"
+"As repr(), return a string containing a printable representation of an\n"
+"object, but escape the non-ASCII characters in the string returned by\n"
+"repr() using \\\\x, \\\\u or \\\\U escapes. This generates a string similar\n"
+"to that returned by repr() in Python 2.");
+
+#define BUILTIN_ASCII_METHODDEF \
+ {"ascii", (PyCFunction)builtin_ascii, METH_O, builtin_ascii__doc__},
+
+PyDoc_STRVAR(builtin_bin__doc__,
+"bin($module, number, /)\n"
+"--\n"
+"\n"
+"Return the binary representation of an integer.\n"
+"\n"
+" >>> bin(2796202)\n"
+" \'0b1010101010101010101010\'");
+
+#define BUILTIN_BIN_METHODDEF \
+ {"bin", (PyCFunction)builtin_bin, METH_O, builtin_bin__doc__},
+
+PyDoc_STRVAR(builtin_callable__doc__,
+"callable($module, obj, /)\n"
+"--\n"
+"\n"
+"Return whether the object is callable (i.e., some kind of function).\n"
+"\n"
+"Note that classes are callable, as are instances of classes with a\n"
+"__call__() method.");
+
+#define BUILTIN_CALLABLE_METHODDEF \
+ {"callable", (PyCFunction)builtin_callable, METH_O, builtin_callable__doc__},
+
+PyDoc_STRVAR(builtin_format__doc__,
+"format($module, value, format_spec=\'\', /)\n"
+"--\n"
+"\n"
+"Return value.__format__(format_spec)\n"
+"\n"
+"format_spec defaults to the empty string.\n"
+"See the Format Specification Mini-Language section of help(\'FORMATTING\') for\n"
+"details.");
+
+#define BUILTIN_FORMAT_METHODDEF \
+ {"format", (PyCFunction)(void(*)(void))builtin_format, METH_FASTCALL, builtin_format__doc__},
+
+static PyObject *
+builtin_format_impl(PyObject *module, PyObject *value, PyObject *format_spec);
+
+static PyObject *
+builtin_format(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ PyObject *value;
+ PyObject *format_spec = NULL;
+
+ if (!_PyArg_CheckPositional("format", nargs, 1, 2)) {
+ goto exit;
+ }
+ value = args[0];
+ if (nargs < 2) {
+ goto skip_optional;
+ }
+ if (!PyUnicode_Check(args[1])) {
+ _PyArg_BadArgument("format", "argument 2", "str", args[1]);
+ goto exit;
+ }
+ if (PyUnicode_READY(args[1]) == -1) {
+ goto exit;
+ }
+ format_spec = args[1];
+skip_optional:
+ return_value = builtin_format_impl(module, value, format_spec);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(builtin_chr__doc__,
+"chr($module, i, /)\n"
+"--\n"
+"\n"
+"Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff.");
+
+#define BUILTIN_CHR_METHODDEF \
+ {"chr", (PyCFunction)builtin_chr, METH_O, builtin_chr__doc__},
+
+static PyObject *
+builtin_chr_impl(PyObject *module, int i);
+
+static PyObject *
+builtin_chr(PyObject *module, PyObject *arg)
+{
+ PyObject *return_value = NULL;
+ int i;
+
+ if (PyFloat_Check(arg)) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument expected, got float" );
+ goto exit;
+ }
+ i = _PyLong_AsInt(arg);
+ if (i == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+ return_value = builtin_chr_impl(module, i);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(builtin_compile__doc__,
+"compile($module, /, source, filename, mode, flags=0,\n"
+" dont_inherit=False, optimize=-1, *, _feature_version=-1)\n"
+"--\n"
+"\n"
+"Compile source into a code object that can be executed by exec() or eval().\n"
+"\n"
+"The source code may represent a Python module, statement or expression.\n"
+"The filename will be used for run-time error messages.\n"
+"The mode must be \'exec\' to compile a module, \'single\' to compile a\n"
+"single (interactive) statement, or \'eval\' to compile an expression.\n"
+"The flags argument, if present, controls which future statements influence\n"
+"the compilation of the code.\n"
+"The dont_inherit argument, if true, stops the compilation inheriting\n"
+"the effects of any future statements in effect in the code calling\n"
+"compile; if absent or false these statements do influence the compilation,\n"
+"in addition to any features explicitly specified.");
+
+#define BUILTIN_COMPILE_METHODDEF \
+ {"compile", (PyCFunction)(void(*)(void))builtin_compile, METH_FASTCALL|METH_KEYWORDS, builtin_compile__doc__},
+
+static PyObject *
+builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename,
+ const char *mode, int flags, int dont_inherit,
+ int optimize, int feature_version);
+
+static PyObject *
+builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"source", "filename", "mode", "flags", "dont_inherit", "optimize", "_feature_version", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "compile", 0};
+ PyObject *argsbuf[7];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3;
+ PyObject *source;
+ PyObject *filename;
+ const char *mode;
+ int flags = 0;
+ int dont_inherit = 0;
+ int optimize = -1;
+ int feature_version = -1;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 6, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ source = args[0];
+ if (!PyUnicode_FSDecoder(args[1], &filename)) {
+ goto exit;
+ }
+ if (!PyUnicode_Check(args[2])) {
+ _PyArg_BadArgument("compile", "argument 'mode'", "str", args[2]);
+ goto exit;
+ }
+ Py_ssize_t mode_length;
+ mode = PyUnicode_AsUTF8AndSize(args[2], &mode_length);
+ if (mode == NULL) {
+ goto exit;
+ }
+ if (strlen(mode) != (size_t)mode_length) {
+ PyErr_SetString(PyExc_ValueError, "embedded null character");
+ goto exit;
+ }
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ if (args[3]) {
+ if (PyFloat_Check(args[3])) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument expected, got float" );
+ goto exit;
+ }
+ flags = _PyLong_AsInt(args[3]);
+ if (flags == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+ if (!--noptargs) {
+ goto skip_optional_pos;
+ }
+ }
+ if (args[4]) {
+ if (PyFloat_Check(args[4])) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument expected, got float" );
+ goto exit;
+ }
+ dont_inherit = _PyLong_AsInt(args[4]);
+ if (dont_inherit == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+ if (!--noptargs) {
+ goto skip_optional_pos;
+ }
+ }
+ if (args[5]) {
+ if (PyFloat_Check(args[5])) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument expected, got float" );
+ goto exit;
+ }
+ optimize = _PyLong_AsInt(args[5]);
+ if (optimize == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+ if (!--noptargs) {
+ goto skip_optional_pos;
+ }
+ }
+skip_optional_pos:
+ if (!noptargs) {
+ goto skip_optional_kwonly;
+ }
+ if (PyFloat_Check(args[6])) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument expected, got float" );
+ goto exit;
+ }
+ feature_version = _PyLong_AsInt(args[6]);
+ if (feature_version == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+skip_optional_kwonly:
+ return_value = builtin_compile_impl(module, source, filename, mode, flags, dont_inherit, optimize, feature_version);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(builtin_divmod__doc__,
+"divmod($module, x, y, /)\n"
+"--\n"
+"\n"
+"Return the tuple (x//y, x%y). Invariant: div*y + mod == x.");
+
+#define BUILTIN_DIVMOD_METHODDEF \
+ {"divmod", (PyCFunction)(void(*)(void))builtin_divmod, METH_FASTCALL, builtin_divmod__doc__},
+
+static PyObject *
+builtin_divmod_impl(PyObject *module, PyObject *x, PyObject *y);
+
+static PyObject *
+builtin_divmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ PyObject *x;
+ PyObject *y;
+
+ if (!_PyArg_CheckPositional("divmod", nargs, 2, 2)) {
+ goto exit;
+ }
+ x = args[0];
+ y = args[1];
+ return_value = builtin_divmod_impl(module, x, y);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(builtin_eval__doc__,
+"eval($module, source, globals=None, locals=None, /)\n"
+"--\n"
+"\n"
+"Evaluate the given source in the context of globals and locals.\n"
+"\n"
+"The source may be a string representing a Python expression\n"
+"or a code object as returned by compile().\n"
+"The globals must be a dictionary and locals can be any mapping,\n"
+"defaulting to the current globals and locals.\n"
+"If only globals is given, locals defaults to it.");
+
+#define BUILTIN_EVAL_METHODDEF \
+ {"eval", (PyCFunction)(void(*)(void))builtin_eval, METH_FASTCALL, builtin_eval__doc__},
+
+static PyObject *
+builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals,
+ PyObject *locals);
+
+static PyObject *
+builtin_eval(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ PyObject *source;
+ PyObject *globals = Py_None;
+ PyObject *locals = Py_None;
+
+ if (!_PyArg_CheckPositional("eval", nargs, 1, 3)) {
+ goto exit;
+ }
+ source = args[0];
+ if (nargs < 2) {
+ goto skip_optional;
+ }
+ globals = args[1];
+ if (nargs < 3) {
+ goto skip_optional;
+ }
+ locals = args[2];
+skip_optional:
+ return_value = builtin_eval_impl(module, source, globals, locals);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(builtin_exec__doc__,
+"exec($module, source, globals=None, locals=None, /)\n"
+"--\n"
+"\n"
+"Execute the given source in the context of globals and locals.\n"
+"\n"
+"The source may be a string representing one or more Python statements\n"
+"or a code object as returned by compile().\n"
+"The globals must be a dictionary and locals can be any mapping,\n"
+"defaulting to the current globals and locals.\n"
+"If only globals is given, locals defaults to it.");
+
+#define BUILTIN_EXEC_METHODDEF \
+ {"exec", (PyCFunction)(void(*)(void))builtin_exec, METH_FASTCALL, builtin_exec__doc__},
+
+static PyObject *
+builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals,
+ PyObject *locals);
+
+static PyObject *
+builtin_exec(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ PyObject *source;
+ PyObject *globals = Py_None;
+ PyObject *locals = Py_None;
+
+ if (!_PyArg_CheckPositional("exec", nargs, 1, 3)) {
+ goto exit;
+ }
+ source = args[0];
+ if (nargs < 2) {
+ goto skip_optional;
+ }
+ globals = args[1];
+ if (nargs < 3) {
+ goto skip_optional;
+ }
+ locals = args[2];
+skip_optional:
+ return_value = builtin_exec_impl(module, source, globals, locals);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(builtin_globals__doc__,
+"globals($module, /)\n"
+"--\n"
+"\n"
+"Return the dictionary containing the current scope\'s global variables.\n"
+"\n"
+"NOTE: Updates to this dictionary *will* affect name lookups in the current\n"
+"global scope and vice-versa.");
+
+#define BUILTIN_GLOBALS_METHODDEF \
+ {"globals", (PyCFunction)builtin_globals, METH_NOARGS, builtin_globals__doc__},
+
+static PyObject *
+builtin_globals_impl(PyObject *module);
+
+static PyObject *
+builtin_globals(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return builtin_globals_impl(module);
+}
+
+PyDoc_STRVAR(builtin_hasattr__doc__,
+"hasattr($module, obj, name, /)\n"
+"--\n"
+"\n"
+"Return whether the object has an attribute with the given name.\n"
+"\n"
+"This is done by calling getattr(obj, name) and catching AttributeError.");
+
+#define BUILTIN_HASATTR_METHODDEF \
+ {"hasattr", (PyCFunction)(void(*)(void))builtin_hasattr, METH_FASTCALL, builtin_hasattr__doc__},
+
+static PyObject *
+builtin_hasattr_impl(PyObject *module, PyObject *obj, PyObject *name);
+
+static PyObject *
+builtin_hasattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ PyObject *obj;
+ PyObject *name;
+
+ if (!_PyArg_CheckPositional("hasattr", nargs, 2, 2)) {
+ goto exit;
+ }
+ obj = args[0];
+ name = args[1];
+ return_value = builtin_hasattr_impl(module, obj, name);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(builtin_id__doc__,
+"id($module, obj, /)\n"
+"--\n"
+"\n"
+"Return the identity of an object.\n"
+"\n"
+"This is guaranteed to be unique among simultaneously existing objects.\n"
+"(CPython uses the object\'s memory address.)");
+
+#define BUILTIN_ID_METHODDEF \
+ {"id", (PyCFunction)builtin_id, METH_O, builtin_id__doc__},
+
+PyDoc_STRVAR(builtin_setattr__doc__,
+"setattr($module, obj, name, value, /)\n"
+"--\n"
+"\n"
+"Sets the named attribute on the given object to the specified value.\n"
+"\n"
+"setattr(x, \'y\', v) is equivalent to ``x.y = v\'\'");
+
+#define BUILTIN_SETATTR_METHODDEF \
+ {"setattr", (PyCFunction)(void(*)(void))builtin_setattr, METH_FASTCALL, builtin_setattr__doc__},
+
+static PyObject *
+builtin_setattr_impl(PyObject *module, PyObject *obj, PyObject *name,
+ PyObject *value);
+
+static PyObject *
+builtin_setattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ PyObject *obj;
+ PyObject *name;
+ PyObject *value;
+
+ if (!_PyArg_CheckPositional("setattr", nargs, 3, 3)) {
+ goto exit;
+ }
+ obj = args[0];
+ name = args[1];
+ value = args[2];
+ return_value = builtin_setattr_impl(module, obj, name, value);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(builtin_delattr__doc__,
+"delattr($module, obj, name, /)\n"
+"--\n"
+"\n"
+"Deletes the named attribute from the given object.\n"
+"\n"
+"delattr(x, \'y\') is equivalent to ``del x.y\'\'");
+
+#define BUILTIN_DELATTR_METHODDEF \
+ {"delattr", (PyCFunction)(void(*)(void))builtin_delattr, METH_FASTCALL, builtin_delattr__doc__},
+
+static PyObject *
+builtin_delattr_impl(PyObject *module, PyObject *obj, PyObject *name);
+
+static PyObject *
+builtin_delattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ PyObject *obj;
+ PyObject *name;
+
+ if (!_PyArg_CheckPositional("delattr", nargs, 2, 2)) {
+ goto exit;
+ }
+ obj = args[0];
+ name = args[1];
+ return_value = builtin_delattr_impl(module, obj, name);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(builtin_hash__doc__,
+"hash($module, obj, /)\n"
+"--\n"
+"\n"
+"Return the hash value for the given object.\n"
+"\n"
+"Two objects that compare equal must also have the same hash value, but the\n"
+"reverse is not necessarily true.");
+
+#define BUILTIN_HASH_METHODDEF \
+ {"hash", (PyCFunction)builtin_hash, METH_O, builtin_hash__doc__},
+
+PyDoc_STRVAR(builtin_hex__doc__,
+"hex($module, number, /)\n"
+"--\n"
+"\n"
+"Return the hexadecimal representation of an integer.\n"
+"\n"
+" >>> hex(12648430)\n"
+" \'0xc0ffee\'");
+
+#define BUILTIN_HEX_METHODDEF \
+ {"hex", (PyCFunction)builtin_hex, METH_O, builtin_hex__doc__},
+
+PyDoc_STRVAR(builtin_len__doc__,
+"len($module, obj, /)\n"
+"--\n"
+"\n"
+"Return the number of items in a container.");
+
+#define BUILTIN_LEN_METHODDEF \
+ {"len", (PyCFunction)builtin_len, METH_O, builtin_len__doc__},
+
+PyDoc_STRVAR(builtin_locals__doc__,
+"locals($module, /)\n"
+"--\n"
+"\n"
+"Return a dictionary containing the current scope\'s local variables.\n"
+"\n"
+"NOTE: Whether or not updates to this dictionary will affect name lookups in\n"
+"the local scope and vice-versa is *implementation dependent* and not\n"
+"covered by any backwards compatibility guarantees.");
+
+#define BUILTIN_LOCALS_METHODDEF \
+ {"locals", (PyCFunction)builtin_locals, METH_NOARGS, builtin_locals__doc__},
+
+static PyObject *
+builtin_locals_impl(PyObject *module);
+
+static PyObject *
+builtin_locals(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return builtin_locals_impl(module);
+}
+
+PyDoc_STRVAR(builtin_oct__doc__,
+"oct($module, number, /)\n"
+"--\n"
+"\n"
+"Return the octal representation of an integer.\n"
+"\n"
+" >>> oct(342391)\n"
+" \'0o1234567\'");
+
+#define BUILTIN_OCT_METHODDEF \
+ {"oct", (PyCFunction)builtin_oct, METH_O, builtin_oct__doc__},
+
+PyDoc_STRVAR(builtin_ord__doc__,
+"ord($module, c, /)\n"
+"--\n"
+"\n"
+"Return the Unicode code point for a one-character string.");
+
+#define BUILTIN_ORD_METHODDEF \
+ {"ord", (PyCFunction)builtin_ord, METH_O, builtin_ord__doc__},
+
+PyDoc_STRVAR(builtin_pow__doc__,
+"pow($module, /, base, exp, mod=None)\n"
+"--\n"
+"\n"
+"Equivalent to base**exp with 2 arguments or base**exp % mod with 3 arguments\n"
+"\n"
+"Some types, such as ints, are able to use a more efficient algorithm when\n"
+"invoked using the three argument form.");
+
+#define BUILTIN_POW_METHODDEF \
+ {"pow", (PyCFunction)(void(*)(void))builtin_pow, METH_FASTCALL|METH_KEYWORDS, builtin_pow__doc__},
+
+static PyObject *
+builtin_pow_impl(PyObject *module, PyObject *base, PyObject *exp,
+ PyObject *mod);
+
+static PyObject *
+builtin_pow(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"base", "exp", "mod", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "pow", 0};
+ PyObject *argsbuf[3];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
+ PyObject *base;
+ PyObject *exp;
+ PyObject *mod = Py_None;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ base = args[0];
+ exp = args[1];
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ mod = args[2];
+skip_optional_pos:
+ return_value = builtin_pow_impl(module, base, exp, mod);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(builtin_input__doc__,
+"input($module, prompt=None, /)\n"
+"--\n"
+"\n"
+"Read a string from standard input. The trailing newline is stripped.\n"
+"\n"
+"The prompt string, if given, is printed to standard output without a\n"
+"trailing newline before reading input.\n"
+"\n"
+"If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError.\n"
+"On *nix systems, readline is used if available.");
+
+#define BUILTIN_INPUT_METHODDEF \
+ {"input", (PyCFunction)(void(*)(void))builtin_input, METH_FASTCALL, builtin_input__doc__},
+
+static PyObject *
+builtin_input_impl(PyObject *module, PyObject *prompt);
+
+static PyObject *
+builtin_input(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ PyObject *prompt = NULL;
+
+ if (!_PyArg_CheckPositional("input", nargs, 0, 1)) {
+ goto exit;
+ }
+ if (nargs < 1) {
+ goto skip_optional;
+ }
+ prompt = args[0];
+skip_optional:
+ return_value = builtin_input_impl(module, prompt);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(builtin_repr__doc__,
+"repr($module, obj, /)\n"
+"--\n"
+"\n"
+"Return the canonical string representation of the object.\n"
+"\n"
+"For many object types, including most builtins, eval(repr(obj)) == obj.");
+
+#define BUILTIN_REPR_METHODDEF \
+ {"repr", (PyCFunction)builtin_repr, METH_O, builtin_repr__doc__},
+
+PyDoc_STRVAR(builtin_round__doc__,
+"round($module, /, number, ndigits=None)\n"
+"--\n"
+"\n"
+"Round a number to a given precision in decimal digits.\n"
+"\n"
+"The return value is an integer if ndigits is omitted or None. Otherwise\n"
+"the return value has the same type as the number. ndigits may be negative.");
+
+#define BUILTIN_ROUND_METHODDEF \
+ {"round", (PyCFunction)(void(*)(void))builtin_round, METH_FASTCALL|METH_KEYWORDS, builtin_round__doc__},
+
+static PyObject *
+builtin_round_impl(PyObject *module, PyObject *number, PyObject *ndigits);
+
+static PyObject *
+builtin_round(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"number", "ndigits", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "round", 0};
+ PyObject *argsbuf[2];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+ PyObject *number;
+ PyObject *ndigits = Py_None;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ number = args[0];
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ ndigits = args[1];
+skip_optional_pos:
+ return_value = builtin_round_impl(module, number, ndigits);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(builtin_sum__doc__,
+"sum($module, iterable, /, start=0)\n"
+"--\n"
+"\n"
+"Return the sum of a \'start\' value (default: 0) plus an iterable of numbers\n"
+"\n"
+"When the iterable is empty, return the start value.\n"
+"This function is intended specifically for use with numeric values and may\n"
+"reject non-numeric types.");
+
+#define BUILTIN_SUM_METHODDEF \
+ {"sum", (PyCFunction)(void(*)(void))builtin_sum, METH_FASTCALL|METH_KEYWORDS, builtin_sum__doc__},
+
+static PyObject *
+builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start);
+
+static PyObject *
+builtin_sum(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"", "start", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "sum", 0};
+ PyObject *argsbuf[2];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+ PyObject *iterable;
+ PyObject *start = NULL;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ iterable = args[0];
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ start = args[1];
+skip_optional_pos:
+ return_value = builtin_sum_impl(module, iterable, start);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(builtin_isinstance__doc__,
+"isinstance($module, obj, class_or_tuple, /)\n"
+"--\n"
+"\n"
+"Return whether an object is an instance of a class or of a subclass thereof.\n"
+"\n"
+"A tuple, as in ``isinstance(x, (A, B, ...))``, may be given as the target to\n"
+"check against. This is equivalent to ``isinstance(x, A) or isinstance(x, B)\n"
+"or ...`` etc.");
+
+#define BUILTIN_ISINSTANCE_METHODDEF \
+ {"isinstance", (PyCFunction)(void(*)(void))builtin_isinstance, METH_FASTCALL, builtin_isinstance__doc__},
+
+static PyObject *
+builtin_isinstance_impl(PyObject *module, PyObject *obj,
+ PyObject *class_or_tuple);
+
+static PyObject *
+builtin_isinstance(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ PyObject *obj;
+ PyObject *class_or_tuple;
+
+ if (!_PyArg_CheckPositional("isinstance", nargs, 2, 2)) {
+ goto exit;
+ }
+ obj = args[0];
+ class_or_tuple = args[1];
+ return_value = builtin_isinstance_impl(module, obj, class_or_tuple);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(builtin_issubclass__doc__,
+"issubclass($module, cls, class_or_tuple, /)\n"
+"--\n"
+"\n"
+"Return whether \'cls\' is a derived from another class or is the same class.\n"
+"\n"
+"A tuple, as in ``issubclass(x, (A, B, ...))``, may be given as the target to\n"
+"check against. This is equivalent to ``issubclass(x, A) or issubclass(x, B)\n"
+"or ...`` etc.");
+
+#define BUILTIN_ISSUBCLASS_METHODDEF \
+ {"issubclass", (PyCFunction)(void(*)(void))builtin_issubclass, METH_FASTCALL, builtin_issubclass__doc__},
+
+static PyObject *
+builtin_issubclass_impl(PyObject *module, PyObject *cls,
+ PyObject *class_or_tuple);
+
+static PyObject *
+builtin_issubclass(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ PyObject *cls;
+ PyObject *class_or_tuple;
+
+ if (!_PyArg_CheckPositional("issubclass", nargs, 2, 2)) {
+ goto exit;
+ }
+ cls = args[0];
+ class_or_tuple = args[1];
+ return_value = builtin_issubclass_impl(module, cls, class_or_tuple);
+
+exit:
+ return return_value;
+}
+/*[clinic end generated code: output=29686a89b739d600 input=a9049054013a1b77]*/
diff --git a/contrib/tools/python3/src/Python/clinic/context.c.h b/contrib/tools/python3/src/Python/clinic/context.c.h
new file mode 100644
index 00000000000..2ac8bf7c0b8
--- /dev/null
+++ b/contrib/tools/python3/src/Python/clinic/context.c.h
@@ -0,0 +1,180 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+PyDoc_STRVAR(_contextvars_Context_get__doc__,
+"get($self, key, default=None, /)\n"
+"--\n"
+"\n"
+"Return the value for `key` if `key` has the value in the context object.\n"
+"\n"
+"If `key` does not exist, return `default`. If `default` is not given,\n"
+"return None.");
+
+#define _CONTEXTVARS_CONTEXT_GET_METHODDEF \
+ {"get", (PyCFunction)(void(*)(void))_contextvars_Context_get, METH_FASTCALL, _contextvars_Context_get__doc__},
+
+static PyObject *
+_contextvars_Context_get_impl(PyContext *self, PyObject *key,
+ PyObject *default_value);
+
+static PyObject *
+_contextvars_Context_get(PyContext *self, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ PyObject *key;
+ PyObject *default_value = Py_None;
+
+ if (!_PyArg_CheckPositional("get", nargs, 1, 2)) {
+ goto exit;
+ }
+ key = args[0];
+ if (nargs < 2) {
+ goto skip_optional;
+ }
+ default_value = args[1];
+skip_optional:
+ return_value = _contextvars_Context_get_impl(self, key, default_value);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(_contextvars_Context_items__doc__,
+"items($self, /)\n"
+"--\n"
+"\n"
+"Return all variables and their values in the context object.\n"
+"\n"
+"The result is returned as a list of 2-tuples (variable, value).");
+
+#define _CONTEXTVARS_CONTEXT_ITEMS_METHODDEF \
+ {"items", (PyCFunction)_contextvars_Context_items, METH_NOARGS, _contextvars_Context_items__doc__},
+
+static PyObject *
+_contextvars_Context_items_impl(PyContext *self);
+
+static PyObject *
+_contextvars_Context_items(PyContext *self, PyObject *Py_UNUSED(ignored))
+{
+ return _contextvars_Context_items_impl(self);
+}
+
+PyDoc_STRVAR(_contextvars_Context_keys__doc__,
+"keys($self, /)\n"
+"--\n"
+"\n"
+"Return a list of all variables in the context object.");
+
+#define _CONTEXTVARS_CONTEXT_KEYS_METHODDEF \
+ {"keys", (PyCFunction)_contextvars_Context_keys, METH_NOARGS, _contextvars_Context_keys__doc__},
+
+static PyObject *
+_contextvars_Context_keys_impl(PyContext *self);
+
+static PyObject *
+_contextvars_Context_keys(PyContext *self, PyObject *Py_UNUSED(ignored))
+{
+ return _contextvars_Context_keys_impl(self);
+}
+
+PyDoc_STRVAR(_contextvars_Context_values__doc__,
+"values($self, /)\n"
+"--\n"
+"\n"
+"Return a list of all variables\' values in the context object.");
+
+#define _CONTEXTVARS_CONTEXT_VALUES_METHODDEF \
+ {"values", (PyCFunction)_contextvars_Context_values, METH_NOARGS, _contextvars_Context_values__doc__},
+
+static PyObject *
+_contextvars_Context_values_impl(PyContext *self);
+
+static PyObject *
+_contextvars_Context_values(PyContext *self, PyObject *Py_UNUSED(ignored))
+{
+ return _contextvars_Context_values_impl(self);
+}
+
+PyDoc_STRVAR(_contextvars_Context_copy__doc__,
+"copy($self, /)\n"
+"--\n"
+"\n"
+"Return a shallow copy of the context object.");
+
+#define _CONTEXTVARS_CONTEXT_COPY_METHODDEF \
+ {"copy", (PyCFunction)_contextvars_Context_copy, METH_NOARGS, _contextvars_Context_copy__doc__},
+
+static PyObject *
+_contextvars_Context_copy_impl(PyContext *self);
+
+static PyObject *
+_contextvars_Context_copy(PyContext *self, PyObject *Py_UNUSED(ignored))
+{
+ return _contextvars_Context_copy_impl(self);
+}
+
+PyDoc_STRVAR(_contextvars_ContextVar_get__doc__,
+"get($self, default=<unrepresentable>, /)\n"
+"--\n"
+"\n"
+"Return a value for the context variable for the current context.\n"
+"\n"
+"If there is no value for the variable in the current context, the method will:\n"
+" * return the value of the default argument of the method, if provided; or\n"
+" * return the default value for the context variable, if it was created\n"
+" with one; or\n"
+" * raise a LookupError.");
+
+#define _CONTEXTVARS_CONTEXTVAR_GET_METHODDEF \
+ {"get", (PyCFunction)(void(*)(void))_contextvars_ContextVar_get, METH_FASTCALL, _contextvars_ContextVar_get__doc__},
+
+static PyObject *
+_contextvars_ContextVar_get_impl(PyContextVar *self, PyObject *default_value);
+
+static PyObject *
+_contextvars_ContextVar_get(PyContextVar *self, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ PyObject *default_value = NULL;
+
+ if (!_PyArg_CheckPositional("get", nargs, 0, 1)) {
+ goto exit;
+ }
+ if (nargs < 1) {
+ goto skip_optional;
+ }
+ default_value = args[0];
+skip_optional:
+ return_value = _contextvars_ContextVar_get_impl(self, default_value);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(_contextvars_ContextVar_set__doc__,
+"set($self, value, /)\n"
+"--\n"
+"\n"
+"Call to set a new value for the context variable in the current context.\n"
+"\n"
+"The required value argument is the new value for the context variable.\n"
+"\n"
+"Returns a Token object that can be used to restore the variable to its previous\n"
+"value via the `ContextVar.reset()` method.");
+
+#define _CONTEXTVARS_CONTEXTVAR_SET_METHODDEF \
+ {"set", (PyCFunction)_contextvars_ContextVar_set, METH_O, _contextvars_ContextVar_set__doc__},
+
+PyDoc_STRVAR(_contextvars_ContextVar_reset__doc__,
+"reset($self, token, /)\n"
+"--\n"
+"\n"
+"Reset the context variable.\n"
+"\n"
+"The variable is reset to the value it had before the `ContextVar.set()` that\n"
+"created the token was used.");
+
+#define _CONTEXTVARS_CONTEXTVAR_RESET_METHODDEF \
+ {"reset", (PyCFunction)_contextvars_ContextVar_reset, METH_O, _contextvars_ContextVar_reset__doc__},
+/*[clinic end generated code: output=f2e42f34e358e179 input=a9049054013a1b77]*/
diff --git a/contrib/tools/python3/src/Python/clinic/import.c.h b/contrib/tools/python3/src/Python/clinic/import.c.h
new file mode 100644
index 00000000000..e4867f34d4e
--- /dev/null
+++ b/contrib/tools/python3/src/Python/clinic/import.c.h
@@ -0,0 +1,457 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+PyDoc_STRVAR(_imp_lock_held__doc__,
+"lock_held($module, /)\n"
+"--\n"
+"\n"
+"Return True if the import lock is currently held, else False.\n"
+"\n"
+"On platforms without threads, return False.");
+
+#define _IMP_LOCK_HELD_METHODDEF \
+ {"lock_held", (PyCFunction)_imp_lock_held, METH_NOARGS, _imp_lock_held__doc__},
+
+static PyObject *
+_imp_lock_held_impl(PyObject *module);
+
+static PyObject *
+_imp_lock_held(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return _imp_lock_held_impl(module);
+}
+
+PyDoc_STRVAR(_imp_acquire_lock__doc__,
+"acquire_lock($module, /)\n"
+"--\n"
+"\n"
+"Acquires the interpreter\'s import lock for the current thread.\n"
+"\n"
+"This lock should be used by import hooks to ensure thread-safety when importing\n"
+"modules. On platforms without threads, this function does nothing.");
+
+#define _IMP_ACQUIRE_LOCK_METHODDEF \
+ {"acquire_lock", (PyCFunction)_imp_acquire_lock, METH_NOARGS, _imp_acquire_lock__doc__},
+
+static PyObject *
+_imp_acquire_lock_impl(PyObject *module);
+
+static PyObject *
+_imp_acquire_lock(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return _imp_acquire_lock_impl(module);
+}
+
+PyDoc_STRVAR(_imp_release_lock__doc__,
+"release_lock($module, /)\n"
+"--\n"
+"\n"
+"Release the interpreter\'s import lock.\n"
+"\n"
+"On platforms without threads, this function does nothing.");
+
+#define _IMP_RELEASE_LOCK_METHODDEF \
+ {"release_lock", (PyCFunction)_imp_release_lock, METH_NOARGS, _imp_release_lock__doc__},
+
+static PyObject *
+_imp_release_lock_impl(PyObject *module);
+
+static PyObject *
+_imp_release_lock(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return _imp_release_lock_impl(module);
+}
+
+PyDoc_STRVAR(_imp__fix_co_filename__doc__,
+"_fix_co_filename($module, code, path, /)\n"
+"--\n"
+"\n"
+"Changes code.co_filename to specify the passed-in file path.\n"
+"\n"
+" code\n"
+" Code object to change.\n"
+" path\n"
+" File path to use.");
+
+#define _IMP__FIX_CO_FILENAME_METHODDEF \
+ {"_fix_co_filename", (PyCFunction)(void(*)(void))_imp__fix_co_filename, METH_FASTCALL, _imp__fix_co_filename__doc__},
+
+static PyObject *
+_imp__fix_co_filename_impl(PyObject *module, PyCodeObject *code,
+ PyObject *path);
+
+static PyObject *
+_imp__fix_co_filename(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ PyCodeObject *code;
+ PyObject *path;
+
+ if (!_PyArg_CheckPositional("_fix_co_filename", nargs, 2, 2)) {
+ goto exit;
+ }
+ if (!PyObject_TypeCheck(args[0], &PyCode_Type)) {
+ _PyArg_BadArgument("_fix_co_filename", "argument 1", (&PyCode_Type)->tp_name, args[0]);
+ goto exit;
+ }
+ code = (PyCodeObject *)args[0];
+ if (!PyUnicode_Check(args[1])) {
+ _PyArg_BadArgument("_fix_co_filename", "argument 2", "str", args[1]);
+ goto exit;
+ }
+ if (PyUnicode_READY(args[1]) == -1) {
+ goto exit;
+ }
+ path = args[1];
+ return_value = _imp__fix_co_filename_impl(module, code, path);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(_imp_create_builtin__doc__,
+"create_builtin($module, spec, /)\n"
+"--\n"
+"\n"
+"Create an extension module.");
+
+#define _IMP_CREATE_BUILTIN_METHODDEF \
+ {"create_builtin", (PyCFunction)_imp_create_builtin, METH_O, _imp_create_builtin__doc__},
+
+PyDoc_STRVAR(_imp_extension_suffixes__doc__,
+"extension_suffixes($module, /)\n"
+"--\n"
+"\n"
+"Returns the list of file suffixes used to identify extension modules.");
+
+#define _IMP_EXTENSION_SUFFIXES_METHODDEF \
+ {"extension_suffixes", (PyCFunction)_imp_extension_suffixes, METH_NOARGS, _imp_extension_suffixes__doc__},
+
+static PyObject *
+_imp_extension_suffixes_impl(PyObject *module);
+
+static PyObject *
+_imp_extension_suffixes(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return _imp_extension_suffixes_impl(module);
+}
+
+PyDoc_STRVAR(_imp_init_frozen__doc__,
+"init_frozen($module, name, /)\n"
+"--\n"
+"\n"
+"Initializes a frozen module.");
+
+#define _IMP_INIT_FROZEN_METHODDEF \
+ {"init_frozen", (PyCFunction)_imp_init_frozen, METH_O, _imp_init_frozen__doc__},
+
+static PyObject *
+_imp_init_frozen_impl(PyObject *module, PyObject *name);
+
+static PyObject *
+_imp_init_frozen(PyObject *module, PyObject *arg)
+{
+ PyObject *return_value = NULL;
+ PyObject *name;
+
+ if (!PyUnicode_Check(arg)) {
+ _PyArg_BadArgument("init_frozen", "argument", "str", arg);
+ goto exit;
+ }
+ if (PyUnicode_READY(arg) == -1) {
+ goto exit;
+ }
+ name = arg;
+ return_value = _imp_init_frozen_impl(module, name);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(_imp_get_frozen_object__doc__,
+"get_frozen_object($module, name, /)\n"
+"--\n"
+"\n"
+"Create a code object for a frozen module.");
+
+#define _IMP_GET_FROZEN_OBJECT_METHODDEF \
+ {"get_frozen_object", (PyCFunction)_imp_get_frozen_object, METH_O, _imp_get_frozen_object__doc__},
+
+static PyObject *
+_imp_get_frozen_object_impl(PyObject *module, PyObject *name);
+
+static PyObject *
+_imp_get_frozen_object(PyObject *module, PyObject *arg)
+{
+ PyObject *return_value = NULL;
+ PyObject *name;
+
+ if (!PyUnicode_Check(arg)) {
+ _PyArg_BadArgument("get_frozen_object", "argument", "str", arg);
+ goto exit;
+ }
+ if (PyUnicode_READY(arg) == -1) {
+ goto exit;
+ }
+ name = arg;
+ return_value = _imp_get_frozen_object_impl(module, name);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(_imp_is_frozen_package__doc__,
+"is_frozen_package($module, name, /)\n"
+"--\n"
+"\n"
+"Returns True if the module name is of a frozen package.");
+
+#define _IMP_IS_FROZEN_PACKAGE_METHODDEF \
+ {"is_frozen_package", (PyCFunction)_imp_is_frozen_package, METH_O, _imp_is_frozen_package__doc__},
+
+static PyObject *
+_imp_is_frozen_package_impl(PyObject *module, PyObject *name);
+
+static PyObject *
+_imp_is_frozen_package(PyObject *module, PyObject *arg)
+{
+ PyObject *return_value = NULL;
+ PyObject *name;
+
+ if (!PyUnicode_Check(arg)) {
+ _PyArg_BadArgument("is_frozen_package", "argument", "str", arg);
+ goto exit;
+ }
+ if (PyUnicode_READY(arg) == -1) {
+ goto exit;
+ }
+ name = arg;
+ return_value = _imp_is_frozen_package_impl(module, name);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(_imp_is_builtin__doc__,
+"is_builtin($module, name, /)\n"
+"--\n"
+"\n"
+"Returns True if the module name corresponds to a built-in module.");
+
+#define _IMP_IS_BUILTIN_METHODDEF \
+ {"is_builtin", (PyCFunction)_imp_is_builtin, METH_O, _imp_is_builtin__doc__},
+
+static PyObject *
+_imp_is_builtin_impl(PyObject *module, PyObject *name);
+
+static PyObject *
+_imp_is_builtin(PyObject *module, PyObject *arg)
+{
+ PyObject *return_value = NULL;
+ PyObject *name;
+
+ if (!PyUnicode_Check(arg)) {
+ _PyArg_BadArgument("is_builtin", "argument", "str", arg);
+ goto exit;
+ }
+ if (PyUnicode_READY(arg) == -1) {
+ goto exit;
+ }
+ name = arg;
+ return_value = _imp_is_builtin_impl(module, name);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(_imp_is_frozen__doc__,
+"is_frozen($module, name, /)\n"
+"--\n"
+"\n"
+"Returns True if the module name corresponds to a frozen module.");
+
+#define _IMP_IS_FROZEN_METHODDEF \
+ {"is_frozen", (PyCFunction)_imp_is_frozen, METH_O, _imp_is_frozen__doc__},
+
+static PyObject *
+_imp_is_frozen_impl(PyObject *module, PyObject *name);
+
+static PyObject *
+_imp_is_frozen(PyObject *module, PyObject *arg)
+{
+ PyObject *return_value = NULL;
+ PyObject *name;
+
+ if (!PyUnicode_Check(arg)) {
+ _PyArg_BadArgument("is_frozen", "argument", "str", arg);
+ goto exit;
+ }
+ if (PyUnicode_READY(arg) == -1) {
+ goto exit;
+ }
+ name = arg;
+ return_value = _imp_is_frozen_impl(module, name);
+
+exit:
+ return return_value;
+}
+
+#if defined(HAVE_DYNAMIC_LOADING)
+
+PyDoc_STRVAR(_imp_create_dynamic__doc__,
+"create_dynamic($module, spec, file=<unrepresentable>, /)\n"
+"--\n"
+"\n"
+"Create an extension module.");
+
+#define _IMP_CREATE_DYNAMIC_METHODDEF \
+ {"create_dynamic", (PyCFunction)(void(*)(void))_imp_create_dynamic, METH_FASTCALL, _imp_create_dynamic__doc__},
+
+static PyObject *
+_imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file);
+
+static PyObject *
+_imp_create_dynamic(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ PyObject *spec;
+ PyObject *file = NULL;
+
+ if (!_PyArg_CheckPositional("create_dynamic", nargs, 1, 2)) {
+ goto exit;
+ }
+ spec = args[0];
+ if (nargs < 2) {
+ goto skip_optional;
+ }
+ file = args[1];
+skip_optional:
+ return_value = _imp_create_dynamic_impl(module, spec, file);
+
+exit:
+ return return_value;
+}
+
+#endif /* defined(HAVE_DYNAMIC_LOADING) */
+
+#if defined(HAVE_DYNAMIC_LOADING)
+
+PyDoc_STRVAR(_imp_exec_dynamic__doc__,
+"exec_dynamic($module, mod, /)\n"
+"--\n"
+"\n"
+"Initialize an extension module.");
+
+#define _IMP_EXEC_DYNAMIC_METHODDEF \
+ {"exec_dynamic", (PyCFunction)_imp_exec_dynamic, METH_O, _imp_exec_dynamic__doc__},
+
+static int
+_imp_exec_dynamic_impl(PyObject *module, PyObject *mod);
+
+static PyObject *
+_imp_exec_dynamic(PyObject *module, PyObject *mod)
+{
+ PyObject *return_value = NULL;
+ int _return_value;
+
+ _return_value = _imp_exec_dynamic_impl(module, mod);
+ if ((_return_value == -1) && PyErr_Occurred()) {
+ goto exit;
+ }
+ return_value = PyLong_FromLong((long)_return_value);
+
+exit:
+ return return_value;
+}
+
+#endif /* defined(HAVE_DYNAMIC_LOADING) */
+
+PyDoc_STRVAR(_imp_exec_builtin__doc__,
+"exec_builtin($module, mod, /)\n"
+"--\n"
+"\n"
+"Initialize a built-in module.");
+
+#define _IMP_EXEC_BUILTIN_METHODDEF \
+ {"exec_builtin", (PyCFunction)_imp_exec_builtin, METH_O, _imp_exec_builtin__doc__},
+
+static int
+_imp_exec_builtin_impl(PyObject *module, PyObject *mod);
+
+static PyObject *
+_imp_exec_builtin(PyObject *module, PyObject *mod)
+{
+ PyObject *return_value = NULL;
+ int _return_value;
+
+ _return_value = _imp_exec_builtin_impl(module, mod);
+ if ((_return_value == -1) && PyErr_Occurred()) {
+ goto exit;
+ }
+ return_value = PyLong_FromLong((long)_return_value);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(_imp_source_hash__doc__,
+"source_hash($module, /, key, source)\n"
+"--\n"
+"\n");
+
+#define _IMP_SOURCE_HASH_METHODDEF \
+ {"source_hash", (PyCFunction)(void(*)(void))_imp_source_hash, METH_FASTCALL|METH_KEYWORDS, _imp_source_hash__doc__},
+
+static PyObject *
+_imp_source_hash_impl(PyObject *module, long key, Py_buffer *source);
+
+static PyObject *
+_imp_source_hash(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"key", "source", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "source_hash", 0};
+ PyObject *argsbuf[2];
+ long key;
+ Py_buffer source = {NULL, NULL};
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (PyFloat_Check(args[0])) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument expected, got float" );
+ goto exit;
+ }
+ key = PyLong_AsLong(args[0]);
+ if (key == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+ if (PyObject_GetBuffer(args[1], &source, PyBUF_SIMPLE) != 0) {
+ goto exit;
+ }
+ if (!PyBuffer_IsContiguous(&source, 'C')) {
+ _PyArg_BadArgument("source_hash", "argument 'source'", "contiguous buffer", args[1]);
+ goto exit;
+ }
+ return_value = _imp_source_hash_impl(module, key, &source);
+
+exit:
+ /* Cleanup for source */
+ if (source.obj) {
+ PyBuffer_Release(&source);
+ }
+
+ return return_value;
+}
+
+#ifndef _IMP_CREATE_DYNAMIC_METHODDEF
+ #define _IMP_CREATE_DYNAMIC_METHODDEF
+#endif /* !defined(_IMP_CREATE_DYNAMIC_METHODDEF) */
+
+#ifndef _IMP_EXEC_DYNAMIC_METHODDEF
+ #define _IMP_EXEC_DYNAMIC_METHODDEF
+#endif /* !defined(_IMP_EXEC_DYNAMIC_METHODDEF) */
+/*[clinic end generated code: output=3dc495e9c64d944e input=a9049054013a1b77]*/
diff --git a/contrib/tools/python3/src/Python/clinic/marshal.c.h b/contrib/tools/python3/src/Python/clinic/marshal.c.h
new file mode 100644
index 00000000000..05d4830c4ab
--- /dev/null
+++ b/contrib/tools/python3/src/Python/clinic/marshal.c.h
@@ -0,0 +1,168 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+PyDoc_STRVAR(marshal_dump__doc__,
+"dump($module, value, file, version=version, /)\n"
+"--\n"
+"\n"
+"Write the value on the open file.\n"
+"\n"
+" value\n"
+" Must be a supported type.\n"
+" file\n"
+" Must be a writeable binary file.\n"
+" version\n"
+" Indicates the data format that dump should use.\n"
+"\n"
+"If the value has (or contains an object that has) an unsupported type, a\n"
+"ValueError exception is raised - but garbage data will also be written\n"
+"to the file. The object will not be properly read back by load().");
+
+#define MARSHAL_DUMP_METHODDEF \
+ {"dump", (PyCFunction)(void(*)(void))marshal_dump, METH_FASTCALL, marshal_dump__doc__},
+
+static PyObject *
+marshal_dump_impl(PyObject *module, PyObject *value, PyObject *file,
+ int version);
+
+static PyObject *
+marshal_dump(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ PyObject *value;
+ PyObject *file;
+ int version = Py_MARSHAL_VERSION;
+
+ if (!_PyArg_CheckPositional("dump", nargs, 2, 3)) {
+ goto exit;
+ }
+ value = args[0];
+ file = args[1];
+ if (nargs < 3) {
+ goto skip_optional;
+ }
+ if (PyFloat_Check(args[2])) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument expected, got float" );
+ goto exit;
+ }
+ version = _PyLong_AsInt(args[2]);
+ if (version == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+skip_optional:
+ return_value = marshal_dump_impl(module, value, file, version);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(marshal_load__doc__,
+"load($module, file, /)\n"
+"--\n"
+"\n"
+"Read one value from the open file and return it.\n"
+"\n"
+" file\n"
+" Must be readable binary file.\n"
+"\n"
+"If no valid value is read (e.g. because the data has a different Python\n"
+"version\'s incompatible marshal format), raise EOFError, ValueError or\n"
+"TypeError.\n"
+"\n"
+"Note: If an object containing an unsupported type was marshalled with\n"
+"dump(), load() will substitute None for the unmarshallable type.");
+
+#define MARSHAL_LOAD_METHODDEF \
+ {"load", (PyCFunction)marshal_load, METH_O, marshal_load__doc__},
+
+PyDoc_STRVAR(marshal_dumps__doc__,
+"dumps($module, value, version=version, /)\n"
+"--\n"
+"\n"
+"Return the bytes object that would be written to a file by dump(value, file).\n"
+"\n"
+" value\n"
+" Must be a supported type.\n"
+" version\n"
+" Indicates the data format that dumps should use.\n"
+"\n"
+"Raise a ValueError exception if value has (or contains an object that has) an\n"
+"unsupported type.");
+
+#define MARSHAL_DUMPS_METHODDEF \
+ {"dumps", (PyCFunction)(void(*)(void))marshal_dumps, METH_FASTCALL, marshal_dumps__doc__},
+
+static PyObject *
+marshal_dumps_impl(PyObject *module, PyObject *value, int version);
+
+static PyObject *
+marshal_dumps(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ PyObject *value;
+ int version = Py_MARSHAL_VERSION;
+
+ if (!_PyArg_CheckPositional("dumps", nargs, 1, 2)) {
+ goto exit;
+ }
+ value = args[0];
+ if (nargs < 2) {
+ goto skip_optional;
+ }
+ if (PyFloat_Check(args[1])) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument expected, got float" );
+ goto exit;
+ }
+ version = _PyLong_AsInt(args[1]);
+ if (version == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+skip_optional:
+ return_value = marshal_dumps_impl(module, value, version);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(marshal_loads__doc__,
+"loads($module, bytes, /)\n"
+"--\n"
+"\n"
+"Convert the bytes-like object to a value.\n"
+"\n"
+"If no valid value is found, raise EOFError, ValueError or TypeError. Extra\n"
+"bytes in the input are ignored.");
+
+#define MARSHAL_LOADS_METHODDEF \
+ {"loads", (PyCFunction)marshal_loads, METH_O, marshal_loads__doc__},
+
+static PyObject *
+marshal_loads_impl(PyObject *module, Py_buffer *bytes);
+
+static PyObject *
+marshal_loads(PyObject *module, PyObject *arg)
+{
+ PyObject *return_value = NULL;
+ Py_buffer bytes = {NULL, NULL};
+
+ if (PyObject_GetBuffer(arg, &bytes, PyBUF_SIMPLE) != 0) {
+ goto exit;
+ }
+ if (!PyBuffer_IsContiguous(&bytes, 'C')) {
+ _PyArg_BadArgument("loads", "argument", "contiguous buffer", arg);
+ goto exit;
+ }
+ return_value = marshal_loads_impl(module, &bytes);
+
+exit:
+ /* Cleanup for bytes */
+ if (bytes.obj) {
+ PyBuffer_Release(&bytes);
+ }
+
+ return return_value;
+}
+/*[clinic end generated code: output=a859dabe8b0afeb6 input=a9049054013a1b77]*/
diff --git a/contrib/tools/python3/src/Python/clinic/sysmodule.c.h b/contrib/tools/python3/src/Python/clinic/sysmodule.c.h
new file mode 100644
index 00000000000..4615ebaab5d
--- /dev/null
+++ b/contrib/tools/python3/src/Python/clinic/sysmodule.c.h
@@ -0,0 +1,973 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+PyDoc_STRVAR(sys_addaudithook__doc__,
+"addaudithook($module, /, hook)\n"
+"--\n"
+"\n"
+"Adds a new audit hook callback.");
+
+#define SYS_ADDAUDITHOOK_METHODDEF \
+ {"addaudithook", (PyCFunction)(void(*)(void))sys_addaudithook, METH_FASTCALL|METH_KEYWORDS, sys_addaudithook__doc__},
+
+static PyObject *
+sys_addaudithook_impl(PyObject *module, PyObject *hook);
+
+static PyObject *
+sys_addaudithook(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"hook", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "addaudithook", 0};
+ PyObject *argsbuf[1];
+ PyObject *hook;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ hook = args[0];
+ return_value = sys_addaudithook_impl(module, hook);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(sys_displayhook__doc__,
+"displayhook($module, object, /)\n"
+"--\n"
+"\n"
+"Print an object to sys.stdout and also save it in builtins._");
+
+#define SYS_DISPLAYHOOK_METHODDEF \
+ {"displayhook", (PyCFunction)sys_displayhook, METH_O, sys_displayhook__doc__},
+
+PyDoc_STRVAR(sys_excepthook__doc__,
+"excepthook($module, exctype, value, traceback, /)\n"
+"--\n"
+"\n"
+"Handle an exception by displaying it with a traceback on sys.stderr.");
+
+#define SYS_EXCEPTHOOK_METHODDEF \
+ {"excepthook", (PyCFunction)(void(*)(void))sys_excepthook, METH_FASTCALL, sys_excepthook__doc__},
+
+static PyObject *
+sys_excepthook_impl(PyObject *module, PyObject *exctype, PyObject *value,
+ PyObject *traceback);
+
+static PyObject *
+sys_excepthook(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ PyObject *exctype;
+ PyObject *value;
+ PyObject *traceback;
+
+ if (!_PyArg_CheckPositional("excepthook", nargs, 3, 3)) {
+ goto exit;
+ }
+ exctype = args[0];
+ value = args[1];
+ traceback = args[2];
+ return_value = sys_excepthook_impl(module, exctype, value, traceback);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(sys_exc_info__doc__,
+"exc_info($module, /)\n"
+"--\n"
+"\n"
+"Return current exception information: (type, value, traceback).\n"
+"\n"
+"Return information about the most recent exception caught by an except\n"
+"clause in the current stack frame or in an older stack frame.");
+
+#define SYS_EXC_INFO_METHODDEF \
+ {"exc_info", (PyCFunction)sys_exc_info, METH_NOARGS, sys_exc_info__doc__},
+
+static PyObject *
+sys_exc_info_impl(PyObject *module);
+
+static PyObject *
+sys_exc_info(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return sys_exc_info_impl(module);
+}
+
+PyDoc_STRVAR(sys_unraisablehook__doc__,
+"unraisablehook($module, unraisable, /)\n"
+"--\n"
+"\n"
+"Handle an unraisable exception.\n"
+"\n"
+"The unraisable argument has the following attributes:\n"
+"\n"
+"* exc_type: Exception type.\n"
+"* exc_value: Exception value, can be None.\n"
+"* exc_traceback: Exception traceback, can be None.\n"
+"* err_msg: Error message, can be None.\n"
+"* object: Object causing the exception, can be None.");
+
+#define SYS_UNRAISABLEHOOK_METHODDEF \
+ {"unraisablehook", (PyCFunction)sys_unraisablehook, METH_O, sys_unraisablehook__doc__},
+
+PyDoc_STRVAR(sys_exit__doc__,
+"exit($module, status=None, /)\n"
+"--\n"
+"\n"
+"Exit the interpreter by raising SystemExit(status).\n"
+"\n"
+"If the status is omitted or None, it defaults to zero (i.e., success).\n"
+"If the status is an integer, it will be used as the system exit status.\n"
+"If it is another kind of object, it will be printed and the system\n"
+"exit status will be one (i.e., failure).");
+
+#define SYS_EXIT_METHODDEF \
+ {"exit", (PyCFunction)(void(*)(void))sys_exit, METH_FASTCALL, sys_exit__doc__},
+
+static PyObject *
+sys_exit_impl(PyObject *module, PyObject *status);
+
+static PyObject *
+sys_exit(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ PyObject *status = Py_None;
+
+ if (!_PyArg_CheckPositional("exit", nargs, 0, 1)) {
+ goto exit;
+ }
+ if (nargs < 1) {
+ goto skip_optional;
+ }
+ status = args[0];
+skip_optional:
+ return_value = sys_exit_impl(module, status);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(sys_getdefaultencoding__doc__,
+"getdefaultencoding($module, /)\n"
+"--\n"
+"\n"
+"Return the current default encoding used by the Unicode implementation.");
+
+#define SYS_GETDEFAULTENCODING_METHODDEF \
+ {"getdefaultencoding", (PyCFunction)sys_getdefaultencoding, METH_NOARGS, sys_getdefaultencoding__doc__},
+
+static PyObject *
+sys_getdefaultencoding_impl(PyObject *module);
+
+static PyObject *
+sys_getdefaultencoding(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return sys_getdefaultencoding_impl(module);
+}
+
+PyDoc_STRVAR(sys_getfilesystemencoding__doc__,
+"getfilesystemencoding($module, /)\n"
+"--\n"
+"\n"
+"Return the encoding used to convert Unicode filenames to OS filenames.");
+
+#define SYS_GETFILESYSTEMENCODING_METHODDEF \
+ {"getfilesystemencoding", (PyCFunction)sys_getfilesystemencoding, METH_NOARGS, sys_getfilesystemencoding__doc__},
+
+static PyObject *
+sys_getfilesystemencoding_impl(PyObject *module);
+
+static PyObject *
+sys_getfilesystemencoding(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return sys_getfilesystemencoding_impl(module);
+}
+
+PyDoc_STRVAR(sys_getfilesystemencodeerrors__doc__,
+"getfilesystemencodeerrors($module, /)\n"
+"--\n"
+"\n"
+"Return the error mode used Unicode to OS filename conversion.");
+
+#define SYS_GETFILESYSTEMENCODEERRORS_METHODDEF \
+ {"getfilesystemencodeerrors", (PyCFunction)sys_getfilesystemencodeerrors, METH_NOARGS, sys_getfilesystemencodeerrors__doc__},
+
+static PyObject *
+sys_getfilesystemencodeerrors_impl(PyObject *module);
+
+static PyObject *
+sys_getfilesystemencodeerrors(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return sys_getfilesystemencodeerrors_impl(module);
+}
+
+PyDoc_STRVAR(sys_intern__doc__,
+"intern($module, string, /)\n"
+"--\n"
+"\n"
+"``Intern\'\' the given string.\n"
+"\n"
+"This enters the string in the (global) table of interned strings whose\n"
+"purpose is to speed up dictionary lookups. Return the string itself or\n"
+"the previously interned string object with the same value.");
+
+#define SYS_INTERN_METHODDEF \
+ {"intern", (PyCFunction)sys_intern, METH_O, sys_intern__doc__},
+
+static PyObject *
+sys_intern_impl(PyObject *module, PyObject *s);
+
+static PyObject *
+sys_intern(PyObject *module, PyObject *arg)
+{
+ PyObject *return_value = NULL;
+ PyObject *s;
+
+ if (!PyUnicode_Check(arg)) {
+ _PyArg_BadArgument("intern", "argument", "str", arg);
+ goto exit;
+ }
+ if (PyUnicode_READY(arg) == -1) {
+ goto exit;
+ }
+ s = arg;
+ return_value = sys_intern_impl(module, s);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(sys_gettrace__doc__,
+"gettrace($module, /)\n"
+"--\n"
+"\n"
+"Return the global debug tracing function set with sys.settrace.\n"
+"\n"
+"See the debugger chapter in the library manual.");
+
+#define SYS_GETTRACE_METHODDEF \
+ {"gettrace", (PyCFunction)sys_gettrace, METH_NOARGS, sys_gettrace__doc__},
+
+static PyObject *
+sys_gettrace_impl(PyObject *module);
+
+static PyObject *
+sys_gettrace(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return sys_gettrace_impl(module);
+}
+
+PyDoc_STRVAR(sys_getprofile__doc__,
+"getprofile($module, /)\n"
+"--\n"
+"\n"
+"Return the profiling function set with sys.setprofile.\n"
+"\n"
+"See the profiler chapter in the library manual.");
+
+#define SYS_GETPROFILE_METHODDEF \
+ {"getprofile", (PyCFunction)sys_getprofile, METH_NOARGS, sys_getprofile__doc__},
+
+static PyObject *
+sys_getprofile_impl(PyObject *module);
+
+static PyObject *
+sys_getprofile(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return sys_getprofile_impl(module);
+}
+
+PyDoc_STRVAR(sys_setswitchinterval__doc__,
+"setswitchinterval($module, interval, /)\n"
+"--\n"
+"\n"
+"Set the ideal thread switching delay inside the Python interpreter.\n"
+"\n"
+"The actual frequency of switching threads can be lower if the\n"
+"interpreter executes long sequences of uninterruptible code\n"
+"(this is implementation-specific and workload-dependent).\n"
+"\n"
+"The parameter must represent the desired switching delay in seconds\n"
+"A typical value is 0.005 (5 milliseconds).");
+
+#define SYS_SETSWITCHINTERVAL_METHODDEF \
+ {"setswitchinterval", (PyCFunction)sys_setswitchinterval, METH_O, sys_setswitchinterval__doc__},
+
+static PyObject *
+sys_setswitchinterval_impl(PyObject *module, double interval);
+
+static PyObject *
+sys_setswitchinterval(PyObject *module, PyObject *arg)
+{
+ PyObject *return_value = NULL;
+ double interval;
+
+ if (PyFloat_CheckExact(arg)) {
+ interval = PyFloat_AS_DOUBLE(arg);
+ }
+ else
+ {
+ interval = PyFloat_AsDouble(arg);
+ if (interval == -1.0 && PyErr_Occurred()) {
+ goto exit;
+ }
+ }
+ return_value = sys_setswitchinterval_impl(module, interval);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(sys_getswitchinterval__doc__,
+"getswitchinterval($module, /)\n"
+"--\n"
+"\n"
+"Return the current thread switch interval; see sys.setswitchinterval().");
+
+#define SYS_GETSWITCHINTERVAL_METHODDEF \
+ {"getswitchinterval", (PyCFunction)sys_getswitchinterval, METH_NOARGS, sys_getswitchinterval__doc__},
+
+static double
+sys_getswitchinterval_impl(PyObject *module);
+
+static PyObject *
+sys_getswitchinterval(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ PyObject *return_value = NULL;
+ double _return_value;
+
+ _return_value = sys_getswitchinterval_impl(module);
+ if ((_return_value == -1.0) && PyErr_Occurred()) {
+ goto exit;
+ }
+ return_value = PyFloat_FromDouble(_return_value);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(sys_setrecursionlimit__doc__,
+"setrecursionlimit($module, limit, /)\n"
+"--\n"
+"\n"
+"Set the maximum depth of the Python interpreter stack to n.\n"
+"\n"
+"This limit prevents infinite recursion from causing an overflow of the C\n"
+"stack and crashing Python. The highest possible limit is platform-\n"
+"dependent.");
+
+#define SYS_SETRECURSIONLIMIT_METHODDEF \
+ {"setrecursionlimit", (PyCFunction)sys_setrecursionlimit, METH_O, sys_setrecursionlimit__doc__},
+
+static PyObject *
+sys_setrecursionlimit_impl(PyObject *module, int new_limit);
+
+static PyObject *
+sys_setrecursionlimit(PyObject *module, PyObject *arg)
+{
+ PyObject *return_value = NULL;
+ int new_limit;
+
+ if (PyFloat_Check(arg)) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument expected, got float" );
+ goto exit;
+ }
+ new_limit = _PyLong_AsInt(arg);
+ if (new_limit == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+ return_value = sys_setrecursionlimit_impl(module, new_limit);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(sys_set_coroutine_origin_tracking_depth__doc__,
+"set_coroutine_origin_tracking_depth($module, /, depth)\n"
+"--\n"
+"\n"
+"Enable or disable origin tracking for coroutine objects in this thread.\n"
+"\n"
+"Coroutine objects will track \'depth\' frames of traceback information\n"
+"about where they came from, available in their cr_origin attribute.\n"
+"\n"
+"Set a depth of 0 to disable.");
+
+#define SYS_SET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF \
+ {"set_coroutine_origin_tracking_depth", (PyCFunction)(void(*)(void))sys_set_coroutine_origin_tracking_depth, METH_FASTCALL|METH_KEYWORDS, sys_set_coroutine_origin_tracking_depth__doc__},
+
+static PyObject *
+sys_set_coroutine_origin_tracking_depth_impl(PyObject *module, int depth);
+
+static PyObject *
+sys_set_coroutine_origin_tracking_depth(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"depth", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "set_coroutine_origin_tracking_depth", 0};
+ PyObject *argsbuf[1];
+ int depth;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (PyFloat_Check(args[0])) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument expected, got float" );
+ goto exit;
+ }
+ depth = _PyLong_AsInt(args[0]);
+ if (depth == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+ return_value = sys_set_coroutine_origin_tracking_depth_impl(module, depth);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(sys_get_coroutine_origin_tracking_depth__doc__,
+"get_coroutine_origin_tracking_depth($module, /)\n"
+"--\n"
+"\n"
+"Check status of origin tracking for coroutine objects in this thread.");
+
+#define SYS_GET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF \
+ {"get_coroutine_origin_tracking_depth", (PyCFunction)sys_get_coroutine_origin_tracking_depth, METH_NOARGS, sys_get_coroutine_origin_tracking_depth__doc__},
+
+static int
+sys_get_coroutine_origin_tracking_depth_impl(PyObject *module);
+
+static PyObject *
+sys_get_coroutine_origin_tracking_depth(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ PyObject *return_value = NULL;
+ int _return_value;
+
+ _return_value = sys_get_coroutine_origin_tracking_depth_impl(module);
+ if ((_return_value == -1) && PyErr_Occurred()) {
+ goto exit;
+ }
+ return_value = PyLong_FromLong((long)_return_value);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(sys_get_asyncgen_hooks__doc__,
+"get_asyncgen_hooks($module, /)\n"
+"--\n"
+"\n"
+"Return the installed asynchronous generators hooks.\n"
+"\n"
+"This returns a namedtuple of the form (firstiter, finalizer).");
+
+#define SYS_GET_ASYNCGEN_HOOKS_METHODDEF \
+ {"get_asyncgen_hooks", (PyCFunction)sys_get_asyncgen_hooks, METH_NOARGS, sys_get_asyncgen_hooks__doc__},
+
+static PyObject *
+sys_get_asyncgen_hooks_impl(PyObject *module);
+
+static PyObject *
+sys_get_asyncgen_hooks(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return sys_get_asyncgen_hooks_impl(module);
+}
+
+PyDoc_STRVAR(sys_getrecursionlimit__doc__,
+"getrecursionlimit($module, /)\n"
+"--\n"
+"\n"
+"Return the current value of the recursion limit.\n"
+"\n"
+"The recursion limit is the maximum depth of the Python interpreter\n"
+"stack. This limit prevents infinite recursion from causing an overflow\n"
+"of the C stack and crashing Python.");
+
+#define SYS_GETRECURSIONLIMIT_METHODDEF \
+ {"getrecursionlimit", (PyCFunction)sys_getrecursionlimit, METH_NOARGS, sys_getrecursionlimit__doc__},
+
+static PyObject *
+sys_getrecursionlimit_impl(PyObject *module);
+
+static PyObject *
+sys_getrecursionlimit(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return sys_getrecursionlimit_impl(module);
+}
+
+#if defined(MS_WINDOWS)
+
+PyDoc_STRVAR(sys_getwindowsversion__doc__,
+"getwindowsversion($module, /)\n"
+"--\n"
+"\n"
+"Return info about the running version of Windows as a named tuple.\n"
+"\n"
+"The members are named: major, minor, build, platform, service_pack,\n"
+"service_pack_major, service_pack_minor, suite_mask, product_type and\n"
+"platform_version. For backward compatibility, only the first 5 items\n"
+"are available by indexing. All elements are numbers, except\n"
+"service_pack and platform_type which are strings, and platform_version\n"
+"which is a 3-tuple. Platform is always 2. Product_type may be 1 for a\n"
+"workstation, 2 for a domain controller, 3 for a server.\n"
+"Platform_version is a 3-tuple containing a version number that is\n"
+"intended for identifying the OS rather than feature detection.");
+
+#define SYS_GETWINDOWSVERSION_METHODDEF \
+ {"getwindowsversion", (PyCFunction)sys_getwindowsversion, METH_NOARGS, sys_getwindowsversion__doc__},
+
+static PyObject *
+sys_getwindowsversion_impl(PyObject *module);
+
+static PyObject *
+sys_getwindowsversion(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return sys_getwindowsversion_impl(module);
+}
+
+#endif /* defined(MS_WINDOWS) */
+
+#if defined(MS_WINDOWS)
+
+PyDoc_STRVAR(sys__enablelegacywindowsfsencoding__doc__,
+"_enablelegacywindowsfsencoding($module, /)\n"
+"--\n"
+"\n"
+"Changes the default filesystem encoding to mbcs:replace.\n"
+"\n"
+"This is done for consistency with earlier versions of Python. See PEP\n"
+"529 for more information.\n"
+"\n"
+"This is equivalent to defining the PYTHONLEGACYWINDOWSFSENCODING\n"
+"environment variable before launching Python.");
+
+#define SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF \
+ {"_enablelegacywindowsfsencoding", (PyCFunction)sys__enablelegacywindowsfsencoding, METH_NOARGS, sys__enablelegacywindowsfsencoding__doc__},
+
+static PyObject *
+sys__enablelegacywindowsfsencoding_impl(PyObject *module);
+
+static PyObject *
+sys__enablelegacywindowsfsencoding(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return sys__enablelegacywindowsfsencoding_impl(module);
+}
+
+#endif /* defined(MS_WINDOWS) */
+
+#if defined(HAVE_DLOPEN)
+
+PyDoc_STRVAR(sys_setdlopenflags__doc__,
+"setdlopenflags($module, flags, /)\n"
+"--\n"
+"\n"
+"Set the flags used by the interpreter for dlopen calls.\n"
+"\n"
+"This is used, for example, when the interpreter loads extension\n"
+"modules. Among other things, this will enable a lazy resolving of\n"
+"symbols when importing a module, if called as sys.setdlopenflags(0).\n"
+"To share symbols across extension modules, call as\n"
+"sys.setdlopenflags(os.RTLD_GLOBAL). Symbolic names for the flag\n"
+"modules can be found in the os module (RTLD_xxx constants, e.g.\n"
+"os.RTLD_LAZY).");
+
+#define SYS_SETDLOPENFLAGS_METHODDEF \
+ {"setdlopenflags", (PyCFunction)sys_setdlopenflags, METH_O, sys_setdlopenflags__doc__},
+
+static PyObject *
+sys_setdlopenflags_impl(PyObject *module, int new_val);
+
+static PyObject *
+sys_setdlopenflags(PyObject *module, PyObject *arg)
+{
+ PyObject *return_value = NULL;
+ int new_val;
+
+ if (PyFloat_Check(arg)) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument expected, got float" );
+ goto exit;
+ }
+ new_val = _PyLong_AsInt(arg);
+ if (new_val == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+ return_value = sys_setdlopenflags_impl(module, new_val);
+
+exit:
+ return return_value;
+}
+
+#endif /* defined(HAVE_DLOPEN) */
+
+#if defined(HAVE_DLOPEN)
+
+PyDoc_STRVAR(sys_getdlopenflags__doc__,
+"getdlopenflags($module, /)\n"
+"--\n"
+"\n"
+"Return the current value of the flags that are used for dlopen calls.\n"
+"\n"
+"The flag constants are defined in the os module.");
+
+#define SYS_GETDLOPENFLAGS_METHODDEF \
+ {"getdlopenflags", (PyCFunction)sys_getdlopenflags, METH_NOARGS, sys_getdlopenflags__doc__},
+
+static PyObject *
+sys_getdlopenflags_impl(PyObject *module);
+
+static PyObject *
+sys_getdlopenflags(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return sys_getdlopenflags_impl(module);
+}
+
+#endif /* defined(HAVE_DLOPEN) */
+
+#if defined(USE_MALLOPT)
+
+PyDoc_STRVAR(sys_mdebug__doc__,
+"mdebug($module, flag, /)\n"
+"--\n"
+"\n");
+
+#define SYS_MDEBUG_METHODDEF \
+ {"mdebug", (PyCFunction)sys_mdebug, METH_O, sys_mdebug__doc__},
+
+static PyObject *
+sys_mdebug_impl(PyObject *module, int flag);
+
+static PyObject *
+sys_mdebug(PyObject *module, PyObject *arg)
+{
+ PyObject *return_value = NULL;
+ int flag;
+
+ if (PyFloat_Check(arg)) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument expected, got float" );
+ goto exit;
+ }
+ flag = _PyLong_AsInt(arg);
+ if (flag == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+ return_value = sys_mdebug_impl(module, flag);
+
+exit:
+ return return_value;
+}
+
+#endif /* defined(USE_MALLOPT) */
+
+PyDoc_STRVAR(sys_getrefcount__doc__,
+"getrefcount($module, object, /)\n"
+"--\n"
+"\n"
+"Return the reference count of object.\n"
+"\n"
+"The count returned is generally one higher than you might expect,\n"
+"because it includes the (temporary) reference as an argument to\n"
+"getrefcount().");
+
+#define SYS_GETREFCOUNT_METHODDEF \
+ {"getrefcount", (PyCFunction)sys_getrefcount, METH_O, sys_getrefcount__doc__},
+
+static Py_ssize_t
+sys_getrefcount_impl(PyObject *module, PyObject *object);
+
+static PyObject *
+sys_getrefcount(PyObject *module, PyObject *object)
+{
+ PyObject *return_value = NULL;
+ Py_ssize_t _return_value;
+
+ _return_value = sys_getrefcount_impl(module, object);
+ if ((_return_value == -1) && PyErr_Occurred()) {
+ goto exit;
+ }
+ return_value = PyLong_FromSsize_t(_return_value);
+
+exit:
+ return return_value;
+}
+
+#if defined(Py_REF_DEBUG)
+
+PyDoc_STRVAR(sys_gettotalrefcount__doc__,
+"gettotalrefcount($module, /)\n"
+"--\n"
+"\n");
+
+#define SYS_GETTOTALREFCOUNT_METHODDEF \
+ {"gettotalrefcount", (PyCFunction)sys_gettotalrefcount, METH_NOARGS, sys_gettotalrefcount__doc__},
+
+static Py_ssize_t
+sys_gettotalrefcount_impl(PyObject *module);
+
+static PyObject *
+sys_gettotalrefcount(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ PyObject *return_value = NULL;
+ Py_ssize_t _return_value;
+
+ _return_value = sys_gettotalrefcount_impl(module);
+ if ((_return_value == -1) && PyErr_Occurred()) {
+ goto exit;
+ }
+ return_value = PyLong_FromSsize_t(_return_value);
+
+exit:
+ return return_value;
+}
+
+#endif /* defined(Py_REF_DEBUG) */
+
+PyDoc_STRVAR(sys_getallocatedblocks__doc__,
+"getallocatedblocks($module, /)\n"
+"--\n"
+"\n"
+"Return the number of memory blocks currently allocated.");
+
+#define SYS_GETALLOCATEDBLOCKS_METHODDEF \
+ {"getallocatedblocks", (PyCFunction)sys_getallocatedblocks, METH_NOARGS, sys_getallocatedblocks__doc__},
+
+static Py_ssize_t
+sys_getallocatedblocks_impl(PyObject *module);
+
+static PyObject *
+sys_getallocatedblocks(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ PyObject *return_value = NULL;
+ Py_ssize_t _return_value;
+
+ _return_value = sys_getallocatedblocks_impl(module);
+ if ((_return_value == -1) && PyErr_Occurred()) {
+ goto exit;
+ }
+ return_value = PyLong_FromSsize_t(_return_value);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(sys__getframe__doc__,
+"_getframe($module, depth=0, /)\n"
+"--\n"
+"\n"
+"Return a frame object from the call stack.\n"
+"\n"
+"If optional integer depth is given, return the frame object that many\n"
+"calls below the top of the stack. If that is deeper than the call\n"
+"stack, ValueError is raised. The default for depth is zero, returning\n"
+"the frame at the top of the call stack.\n"
+"\n"
+"This function should be used for internal and specialized purposes\n"
+"only.");
+
+#define SYS__GETFRAME_METHODDEF \
+ {"_getframe", (PyCFunction)(void(*)(void))sys__getframe, METH_FASTCALL, sys__getframe__doc__},
+
+static PyObject *
+sys__getframe_impl(PyObject *module, int depth);
+
+static PyObject *
+sys__getframe(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ int depth = 0;
+
+ if (!_PyArg_CheckPositional("_getframe", nargs, 0, 1)) {
+ goto exit;
+ }
+ if (nargs < 1) {
+ goto skip_optional;
+ }
+ if (PyFloat_Check(args[0])) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument expected, got float" );
+ goto exit;
+ }
+ depth = _PyLong_AsInt(args[0]);
+ if (depth == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+skip_optional:
+ return_value = sys__getframe_impl(module, depth);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(sys__current_frames__doc__,
+"_current_frames($module, /)\n"
+"--\n"
+"\n"
+"Return a dict mapping each thread\'s thread id to its current stack frame.\n"
+"\n"
+"This function should be used for specialized purposes only.");
+
+#define SYS__CURRENT_FRAMES_METHODDEF \
+ {"_current_frames", (PyCFunction)sys__current_frames, METH_NOARGS, sys__current_frames__doc__},
+
+static PyObject *
+sys__current_frames_impl(PyObject *module);
+
+static PyObject *
+sys__current_frames(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return sys__current_frames_impl(module);
+}
+
+PyDoc_STRVAR(sys_call_tracing__doc__,
+"call_tracing($module, func, args, /)\n"
+"--\n"
+"\n"
+"Call func(*args), while tracing is enabled.\n"
+"\n"
+"The tracing state is saved, and restored afterwards. This is intended\n"
+"to be called from a debugger from a checkpoint, to recursively debug\n"
+"some other code.");
+
+#define SYS_CALL_TRACING_METHODDEF \
+ {"call_tracing", (PyCFunction)(void(*)(void))sys_call_tracing, METH_FASTCALL, sys_call_tracing__doc__},
+
+static PyObject *
+sys_call_tracing_impl(PyObject *module, PyObject *func, PyObject *funcargs);
+
+static PyObject *
+sys_call_tracing(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ PyObject *func;
+ PyObject *funcargs;
+
+ if (!_PyArg_CheckPositional("call_tracing", nargs, 2, 2)) {
+ goto exit;
+ }
+ func = args[0];
+ if (!PyTuple_Check(args[1])) {
+ _PyArg_BadArgument("call_tracing", "argument 2", "tuple", args[1]);
+ goto exit;
+ }
+ funcargs = args[1];
+ return_value = sys_call_tracing_impl(module, func, funcargs);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(sys__debugmallocstats__doc__,
+"_debugmallocstats($module, /)\n"
+"--\n"
+"\n"
+"Print summary info to stderr about the state of pymalloc\'s structures.\n"
+"\n"
+"In Py_DEBUG mode, also perform some expensive internal consistency\n"
+"checks.");
+
+#define SYS__DEBUGMALLOCSTATS_METHODDEF \
+ {"_debugmallocstats", (PyCFunction)sys__debugmallocstats, METH_NOARGS, sys__debugmallocstats__doc__},
+
+static PyObject *
+sys__debugmallocstats_impl(PyObject *module);
+
+static PyObject *
+sys__debugmallocstats(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return sys__debugmallocstats_impl(module);
+}
+
+PyDoc_STRVAR(sys__clear_type_cache__doc__,
+"_clear_type_cache($module, /)\n"
+"--\n"
+"\n"
+"Clear the internal type lookup cache.");
+
+#define SYS__CLEAR_TYPE_CACHE_METHODDEF \
+ {"_clear_type_cache", (PyCFunction)sys__clear_type_cache, METH_NOARGS, sys__clear_type_cache__doc__},
+
+static PyObject *
+sys__clear_type_cache_impl(PyObject *module);
+
+static PyObject *
+sys__clear_type_cache(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return sys__clear_type_cache_impl(module);
+}
+
+PyDoc_STRVAR(sys_is_finalizing__doc__,
+"is_finalizing($module, /)\n"
+"--\n"
+"\n"
+"Return True if Python is exiting.");
+
+#define SYS_IS_FINALIZING_METHODDEF \
+ {"is_finalizing", (PyCFunction)sys_is_finalizing, METH_NOARGS, sys_is_finalizing__doc__},
+
+static PyObject *
+sys_is_finalizing_impl(PyObject *module);
+
+static PyObject *
+sys_is_finalizing(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return sys_is_finalizing_impl(module);
+}
+
+#if defined(ANDROID_API_LEVEL)
+
+PyDoc_STRVAR(sys_getandroidapilevel__doc__,
+"getandroidapilevel($module, /)\n"
+"--\n"
+"\n"
+"Return the build time API version of Android as an integer.");
+
+#define SYS_GETANDROIDAPILEVEL_METHODDEF \
+ {"getandroidapilevel", (PyCFunction)sys_getandroidapilevel, METH_NOARGS, sys_getandroidapilevel__doc__},
+
+static PyObject *
+sys_getandroidapilevel_impl(PyObject *module);
+
+static PyObject *
+sys_getandroidapilevel(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return sys_getandroidapilevel_impl(module);
+}
+
+#endif /* defined(ANDROID_API_LEVEL) */
+
+#ifndef SYS_GETWINDOWSVERSION_METHODDEF
+ #define SYS_GETWINDOWSVERSION_METHODDEF
+#endif /* !defined(SYS_GETWINDOWSVERSION_METHODDEF) */
+
+#ifndef SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF
+ #define SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF
+#endif /* !defined(SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF) */
+
+#ifndef SYS_SETDLOPENFLAGS_METHODDEF
+ #define SYS_SETDLOPENFLAGS_METHODDEF
+#endif /* !defined(SYS_SETDLOPENFLAGS_METHODDEF) */
+
+#ifndef SYS_GETDLOPENFLAGS_METHODDEF
+ #define SYS_GETDLOPENFLAGS_METHODDEF
+#endif /* !defined(SYS_GETDLOPENFLAGS_METHODDEF) */
+
+#ifndef SYS_MDEBUG_METHODDEF
+ #define SYS_MDEBUG_METHODDEF
+#endif /* !defined(SYS_MDEBUG_METHODDEF) */
+
+#ifndef SYS_GETTOTALREFCOUNT_METHODDEF
+ #define SYS_GETTOTALREFCOUNT_METHODDEF
+#endif /* !defined(SYS_GETTOTALREFCOUNT_METHODDEF) */
+
+#ifndef SYS_GETANDROIDAPILEVEL_METHODDEF
+ #define SYS_GETANDROIDAPILEVEL_METHODDEF
+#endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */
+/*[clinic end generated code: output=39eb34a01fb9a919 input=a9049054013a1b77]*/
diff --git a/contrib/tools/python3/src/Python/clinic/traceback.c.h b/contrib/tools/python3/src/Python/clinic/traceback.c.h
new file mode 100644
index 00000000000..04daf2a3766
--- /dev/null
+++ b/contrib/tools/python3/src/Python/clinic/traceback.c.h
@@ -0,0 +1,62 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+PyDoc_STRVAR(tb_new__doc__,
+"TracebackType(tb_next, tb_frame, tb_lasti, tb_lineno)\n"
+"--\n"
+"\n"
+"Create a new traceback object.");
+
+static PyObject *
+tb_new_impl(PyTypeObject *type, PyObject *tb_next, PyFrameObject *tb_frame,
+ int tb_lasti, int tb_lineno);
+
+static PyObject *
+tb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"tb_next", "tb_frame", "tb_lasti", "tb_lineno", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "TracebackType", 0};
+ PyObject *argsbuf[4];
+ PyObject * const *fastargs;
+ Py_ssize_t nargs = PyTuple_GET_SIZE(args);
+ PyObject *tb_next;
+ PyFrameObject *tb_frame;
+ int tb_lasti;
+ int tb_lineno;
+
+ fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 4, 4, 0, argsbuf);
+ if (!fastargs) {
+ goto exit;
+ }
+ tb_next = fastargs[0];
+ if (!PyObject_TypeCheck(fastargs[1], &PyFrame_Type)) {
+ _PyArg_BadArgument("TracebackType", "argument 'tb_frame'", (&PyFrame_Type)->tp_name, fastargs[1]);
+ goto exit;
+ }
+ tb_frame = (PyFrameObject *)fastargs[1];
+ if (PyFloat_Check(fastargs[2])) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument expected, got float" );
+ goto exit;
+ }
+ tb_lasti = _PyLong_AsInt(fastargs[2]);
+ if (tb_lasti == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+ if (PyFloat_Check(fastargs[3])) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument expected, got float" );
+ goto exit;
+ }
+ tb_lineno = _PyLong_AsInt(fastargs[3]);
+ if (tb_lineno == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+ return_value = tb_new_impl(type, tb_next, tb_frame, tb_lasti, tb_lineno);
+
+exit:
+ return return_value;
+}
+/*[clinic end generated code: output=3def6c06248feed8 input=a9049054013a1b77]*/
diff --git a/contrib/tools/python3/src/Python/codecs.c b/contrib/tools/python3/src/Python/codecs.c
new file mode 100644
index 00000000000..0f18c27e5fe
--- /dev/null
+++ b/contrib/tools/python3/src/Python/codecs.c
@@ -0,0 +1,1535 @@
+/* ------------------------------------------------------------------------
+
+ Python Codec Registry and support functions
+
+Written by Marc-Andre Lemburg ([email protected]).
+
+Copyright (c) Corporation for National Research Initiatives.
+
+ ------------------------------------------------------------------------ */
+
+#include "Python.h"
+#include "pycore_interp.h" // PyInterpreterState.codec_search_path
+#include "pycore_pystate.h" // _PyInterpreterState_GET()
+#include "ucnhash.h"
+#include <ctype.h>
+
+const char *Py_hexdigits = "0123456789abcdef";
+
+/* --- Codec Registry ----------------------------------------------------- */
+
+/* Import the standard encodings package which will register the first
+ codec search function.
+
+ This is done in a lazy way so that the Unicode implementation does
+ not downgrade startup time of scripts not needing it.
+
+ ImportErrors are silently ignored by this function. Only one try is
+ made.
+
+*/
+
+static int _PyCodecRegistry_Init(void); /* Forward */
+
+int PyCodec_Register(PyObject *search_function)
+{
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
+ goto onError;
+ if (search_function == NULL) {
+ PyErr_BadArgument();
+ goto onError;
+ }
+ if (!PyCallable_Check(search_function)) {
+ PyErr_SetString(PyExc_TypeError, "argument must be callable");
+ goto onError;
+ }
+ return PyList_Append(interp->codec_search_path, search_function);
+
+ onError:
+ return -1;
+}
+
+extern int _Py_normalize_encoding(const char *, char *, size_t);
+
+/* Convert a string to a normalized Python string(decoded from UTF-8): all characters are
+ converted to lower case, spaces and hyphens are replaced with underscores. */
+
+static
+PyObject *normalizestring(const char *string)
+{
+ size_t len = strlen(string);
+ char *encoding;
+ PyObject *v;
+
+ if (len > PY_SSIZE_T_MAX) {
+ PyErr_SetString(PyExc_OverflowError, "string is too large");
+ return NULL;
+ }
+
+ encoding = PyMem_Malloc(len + 1);
+ if (encoding == NULL)
+ return PyErr_NoMemory();
+
+ if (!_Py_normalize_encoding(string, encoding, len + 1))
+ {
+ PyErr_SetString(PyExc_RuntimeError, "_Py_normalize_encoding() failed");
+ PyMem_Free(encoding);
+ return NULL;
+ }
+
+ v = PyUnicode_FromString(encoding);
+ PyMem_Free(encoding);
+ return v;
+}
+
+/* Lookup the given encoding and return a tuple providing the codec
+ facilities.
+
+ The encoding string is looked up converted to all lower-case
+ characters. This makes encodings looked up through this mechanism
+ effectively case-insensitive.
+
+ If no codec is found, a LookupError is set and NULL returned.
+
+ As side effect, this tries to load the encodings package, if not
+ yet done. This is part of the lazy load strategy for the encodings
+ package.
+
+*/
+
+PyObject *_PyCodec_Lookup(const char *encoding)
+{
+ if (encoding == NULL) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) {
+ return NULL;
+ }
+
+ /* Convert the encoding to a normalized Python string: all
+ characters are converted to lower case, spaces and hyphens are
+ replaced with underscores. */
+ PyObject *v = normalizestring(encoding);
+ if (v == NULL) {
+ return NULL;
+ }
+ PyUnicode_InternInPlace(&v);
+
+ /* First, try to lookup the name in the registry dictionary */
+ PyObject *result = PyDict_GetItemWithError(interp->codec_search_cache, v);
+ if (result != NULL) {
+ Py_INCREF(result);
+ Py_DECREF(v);
+ return result;
+ }
+ else if (PyErr_Occurred()) {
+ goto onError;
+ }
+
+ /* Next, scan the search functions in order of registration */
+ const Py_ssize_t len = PyList_Size(interp->codec_search_path);
+ if (len < 0)
+ goto onError;
+ if (len == 0) {
+ PyErr_SetString(PyExc_LookupError,
+ "no codec search functions registered: "
+ "can't find encoding");
+ goto onError;
+ }
+
+ Py_ssize_t i;
+ for (i = 0; i < len; i++) {
+ PyObject *func;
+
+ func = PyList_GetItem(interp->codec_search_path, i);
+ if (func == NULL)
+ goto onError;
+ result = PyObject_CallOneArg(func, v);
+ if (result == NULL)
+ goto onError;
+ if (result == Py_None) {
+ Py_DECREF(result);
+ continue;
+ }
+ if (!PyTuple_Check(result) || PyTuple_GET_SIZE(result) != 4) {
+ PyErr_SetString(PyExc_TypeError,
+ "codec search functions must return 4-tuples");
+ Py_DECREF(result);
+ goto onError;
+ }
+ break;
+ }
+ if (i == len) {
+ /* XXX Perhaps we should cache misses too ? */
+ PyErr_Format(PyExc_LookupError,
+ "unknown encoding: %s", encoding);
+ goto onError;
+ }
+
+ /* Cache and return the result */
+ if (PyDict_SetItem(interp->codec_search_cache, v, result) < 0) {
+ Py_DECREF(result);
+ goto onError;
+ }
+ Py_DECREF(v);
+ return result;
+
+ onError:
+ Py_DECREF(v);
+ return NULL;
+}
+
+int _PyCodec_Forget(const char *encoding)
+{
+ PyObject *v;
+ int result;
+
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ if (interp->codec_search_path == NULL) {
+ return -1;
+ }
+
+ /* Convert the encoding to a normalized Python string: all
+ characters are converted to lower case, spaces and hyphens are
+ replaced with underscores. */
+ v = normalizestring(encoding);
+ if (v == NULL) {
+ return -1;
+ }
+
+ /* Drop the named codec from the internal cache */
+ result = PyDict_DelItem(interp->codec_search_cache, v);
+ Py_DECREF(v);
+
+ return result;
+}
+
+/* Codec registry encoding check API. */
+
+int PyCodec_KnownEncoding(const char *encoding)
+{
+ PyObject *codecs;
+
+ codecs = _PyCodec_Lookup(encoding);
+ if (!codecs) {
+ PyErr_Clear();
+ return 0;
+ }
+ else {
+ Py_DECREF(codecs);
+ return 1;
+ }
+}
+
+static
+PyObject *args_tuple(PyObject *object,
+ const char *errors)
+{
+ PyObject *args;
+
+ args = PyTuple_New(1 + (errors != NULL));
+ if (args == NULL)
+ return NULL;
+ Py_INCREF(object);
+ PyTuple_SET_ITEM(args,0,object);
+ if (errors) {
+ PyObject *v;
+
+ v = PyUnicode_FromString(errors);
+ if (v == NULL) {
+ Py_DECREF(args);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(args, 1, v);
+ }
+ return args;
+}
+
+/* Helper function to get a codec item */
+
+static
+PyObject *codec_getitem(const char *encoding, int index)
+{
+ PyObject *codecs;
+ PyObject *v;
+
+ codecs = _PyCodec_Lookup(encoding);
+ if (codecs == NULL)
+ return NULL;
+ v = PyTuple_GET_ITEM(codecs, index);
+ Py_DECREF(codecs);
+ Py_INCREF(v);
+ return v;
+}
+
+/* Helper functions to create an incremental codec. */
+static
+PyObject *codec_makeincrementalcodec(PyObject *codec_info,
+ const char *errors,
+ const char *attrname)
+{
+ PyObject *ret, *inccodec;
+
+ inccodec = PyObject_GetAttrString(codec_info, attrname);
+ if (inccodec == NULL)
+ return NULL;
+ if (errors)
+ ret = PyObject_CallFunction(inccodec, "s", errors);
+ else
+ ret = _PyObject_CallNoArg(inccodec);
+ Py_DECREF(inccodec);
+ return ret;
+}
+
+static
+PyObject *codec_getincrementalcodec(const char *encoding,
+ const char *errors,
+ const char *attrname)
+{
+ PyObject *codec_info, *ret;
+
+ codec_info = _PyCodec_Lookup(encoding);
+ if (codec_info == NULL)
+ return NULL;
+ ret = codec_makeincrementalcodec(codec_info, errors, attrname);
+ Py_DECREF(codec_info);
+ return ret;
+}
+
+/* Helper function to create a stream codec. */
+
+static
+PyObject *codec_getstreamcodec(const char *encoding,
+ PyObject *stream,
+ const char *errors,
+ const int index)
+{
+ PyObject *codecs, *streamcodec, *codeccls;
+
+ codecs = _PyCodec_Lookup(encoding);
+ if (codecs == NULL)
+ return NULL;
+
+ codeccls = PyTuple_GET_ITEM(codecs, index);
+ if (errors != NULL)
+ streamcodec = PyObject_CallFunction(codeccls, "Os", stream, errors);
+ else
+ streamcodec = PyObject_CallOneArg(codeccls, stream);
+ Py_DECREF(codecs);
+ return streamcodec;
+}
+
+/* Helpers to work with the result of _PyCodec_Lookup
+
+ */
+PyObject *_PyCodecInfo_GetIncrementalDecoder(PyObject *codec_info,
+ const char *errors)
+{
+ return codec_makeincrementalcodec(codec_info, errors,
+ "incrementaldecoder");
+}
+
+PyObject *_PyCodecInfo_GetIncrementalEncoder(PyObject *codec_info,
+ const char *errors)
+{
+ return codec_makeincrementalcodec(codec_info, errors,
+ "incrementalencoder");
+}
+
+
+/* Convenience APIs to query the Codec registry.
+
+ All APIs return a codec object with incremented refcount.
+
+ */
+
+PyObject *PyCodec_Encoder(const char *encoding)
+{
+ return codec_getitem(encoding, 0);
+}
+
+PyObject *PyCodec_Decoder(const char *encoding)
+{
+ return codec_getitem(encoding, 1);
+}
+
+PyObject *PyCodec_IncrementalEncoder(const char *encoding,
+ const char *errors)
+{
+ return codec_getincrementalcodec(encoding, errors, "incrementalencoder");
+}
+
+PyObject *PyCodec_IncrementalDecoder(const char *encoding,
+ const char *errors)
+{
+ return codec_getincrementalcodec(encoding, errors, "incrementaldecoder");
+}
+
+PyObject *PyCodec_StreamReader(const char *encoding,
+ PyObject *stream,
+ const char *errors)
+{
+ return codec_getstreamcodec(encoding, stream, errors, 2);
+}
+
+PyObject *PyCodec_StreamWriter(const char *encoding,
+ PyObject *stream,
+ const char *errors)
+{
+ return codec_getstreamcodec(encoding, stream, errors, 3);
+}
+
+/* Helper that tries to ensure the reported exception chain indicates the
+ * codec that was invoked to trigger the failure without changing the type
+ * of the exception raised.
+ */
+static void
+wrap_codec_error(const char *operation,
+ const char *encoding)
+{
+ /* TrySetFromCause will replace the active exception with a suitably
+ * updated clone if it can, otherwise it will leave the original
+ * exception alone.
+ */
+ _PyErr_TrySetFromCause("%s with '%s' codec failed",
+ operation, encoding);
+}
+
+/* Encode an object (e.g. a Unicode object) using the given encoding
+ and return the resulting encoded object (usually a Python string).
+
+ errors is passed to the encoder factory as argument if non-NULL. */
+
+static PyObject *
+_PyCodec_EncodeInternal(PyObject *object,
+ PyObject *encoder,
+ const char *encoding,
+ const char *errors)
+{
+ PyObject *args = NULL, *result = NULL;
+ PyObject *v = NULL;
+
+ args = args_tuple(object, errors);
+ if (args == NULL)
+ goto onError;
+
+ result = PyObject_Call(encoder, args, NULL);
+ if (result == NULL) {
+ wrap_codec_error("encoding", encoding);
+ goto onError;
+ }
+
+ if (!PyTuple_Check(result) ||
+ PyTuple_GET_SIZE(result) != 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "encoder must return a tuple (object, integer)");
+ goto onError;
+ }
+ v = PyTuple_GET_ITEM(result,0);
+ Py_INCREF(v);
+ /* We don't check or use the second (integer) entry. */
+
+ Py_DECREF(args);
+ Py_DECREF(encoder);
+ Py_DECREF(result);
+ return v;
+
+ onError:
+ Py_XDECREF(result);
+ Py_XDECREF(args);
+ Py_XDECREF(encoder);
+ return NULL;
+}
+
+/* Decode an object (usually a Python string) using the given encoding
+ and return an equivalent object (e.g. a Unicode object).
+
+ errors is passed to the decoder factory as argument if non-NULL. */
+
+static PyObject *
+_PyCodec_DecodeInternal(PyObject *object,
+ PyObject *decoder,
+ const char *encoding,
+ const char *errors)
+{
+ PyObject *args = NULL, *result = NULL;
+ PyObject *v;
+
+ args = args_tuple(object, errors);
+ if (args == NULL)
+ goto onError;
+
+ result = PyObject_Call(decoder, args, NULL);
+ if (result == NULL) {
+ wrap_codec_error("decoding", encoding);
+ goto onError;
+ }
+ if (!PyTuple_Check(result) ||
+ PyTuple_GET_SIZE(result) != 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "decoder must return a tuple (object,integer)");
+ goto onError;
+ }
+ v = PyTuple_GET_ITEM(result,0);
+ Py_INCREF(v);
+ /* We don't check or use the second (integer) entry. */
+
+ Py_DECREF(args);
+ Py_DECREF(decoder);
+ Py_DECREF(result);
+ return v;
+
+ onError:
+ Py_XDECREF(args);
+ Py_XDECREF(decoder);
+ Py_XDECREF(result);
+ return NULL;
+}
+
+/* Generic encoding/decoding API */
+PyObject *PyCodec_Encode(PyObject *object,
+ const char *encoding,
+ const char *errors)
+{
+ PyObject *encoder;
+
+ encoder = PyCodec_Encoder(encoding);
+ if (encoder == NULL)
+ return NULL;
+
+ return _PyCodec_EncodeInternal(object, encoder, encoding, errors);
+}
+
+PyObject *PyCodec_Decode(PyObject *object,
+ const char *encoding,
+ const char *errors)
+{
+ PyObject *decoder;
+
+ decoder = PyCodec_Decoder(encoding);
+ if (decoder == NULL)
+ return NULL;
+
+ return _PyCodec_DecodeInternal(object, decoder, encoding, errors);
+}
+
+/* Text encoding/decoding API */
+PyObject * _PyCodec_LookupTextEncoding(const char *encoding,
+ const char *alternate_command)
+{
+ _Py_IDENTIFIER(_is_text_encoding);
+ PyObject *codec;
+ PyObject *attr;
+ int is_text_codec;
+
+ codec = _PyCodec_Lookup(encoding);
+ if (codec == NULL)
+ return NULL;
+
+ /* Backwards compatibility: assume any raw tuple describes a text
+ * encoding, and the same for anything lacking the private
+ * attribute.
+ */
+ if (!PyTuple_CheckExact(codec)) {
+ if (_PyObject_LookupAttrId(codec, &PyId__is_text_encoding, &attr) < 0) {
+ Py_DECREF(codec);
+ return NULL;
+ }
+ if (attr != NULL) {
+ is_text_codec = PyObject_IsTrue(attr);
+ Py_DECREF(attr);
+ if (is_text_codec <= 0) {
+ Py_DECREF(codec);
+ if (!is_text_codec)
+ PyErr_Format(PyExc_LookupError,
+ "'%.400s' is not a text encoding; "
+ "use %s to handle arbitrary codecs",
+ encoding, alternate_command);
+ return NULL;
+ }
+ }
+ }
+
+ /* This appears to be a valid text encoding */
+ return codec;
+}
+
+
+static
+PyObject *codec_getitem_checked(const char *encoding,
+ const char *alternate_command,
+ int index)
+{
+ PyObject *codec;
+ PyObject *v;
+
+ codec = _PyCodec_LookupTextEncoding(encoding, alternate_command);
+ if (codec == NULL)
+ return NULL;
+
+ v = PyTuple_GET_ITEM(codec, index);
+ Py_INCREF(v);
+ Py_DECREF(codec);
+ return v;
+}
+
+static PyObject * _PyCodec_TextEncoder(const char *encoding)
+{
+ return codec_getitem_checked(encoding, "codecs.encode()", 0);
+}
+
+static PyObject * _PyCodec_TextDecoder(const char *encoding)
+{
+ return codec_getitem_checked(encoding, "codecs.decode()", 1);
+}
+
+PyObject *_PyCodec_EncodeText(PyObject *object,
+ const char *encoding,
+ const char *errors)
+{
+ PyObject *encoder;
+
+ encoder = _PyCodec_TextEncoder(encoding);
+ if (encoder == NULL)
+ return NULL;
+
+ return _PyCodec_EncodeInternal(object, encoder, encoding, errors);
+}
+
+PyObject *_PyCodec_DecodeText(PyObject *object,
+ const char *encoding,
+ const char *errors)
+{
+ PyObject *decoder;
+
+ decoder = _PyCodec_TextDecoder(encoding);
+ if (decoder == NULL)
+ return NULL;
+
+ return _PyCodec_DecodeInternal(object, decoder, encoding, errors);
+}
+
+/* Register the error handling callback function error under the name
+ name. This function will be called by the codec when it encounters
+ an unencodable characters/undecodable bytes and doesn't know the
+ callback name, when name is specified as the error parameter
+ in the call to the encode/decode function.
+ Return 0 on success, -1 on error */
+int PyCodec_RegisterError(const char *name, PyObject *error)
+{
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
+ return -1;
+ if (!PyCallable_Check(error)) {
+ PyErr_SetString(PyExc_TypeError, "handler must be callable");
+ return -1;
+ }
+ return PyDict_SetItemString(interp->codec_error_registry,
+ name, error);
+}
+
+/* Lookup the error handling callback function registered under the
+ name error. As a special case NULL can be passed, in which case
+ the error handling callback for strict encoding will be returned. */
+PyObject *PyCodec_LookupError(const char *name)
+{
+ PyObject *handler = NULL;
+
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
+ return NULL;
+
+ if (name==NULL)
+ name = "strict";
+ handler = _PyDict_GetItemStringWithError(interp->codec_error_registry, name);
+ if (handler) {
+ Py_INCREF(handler);
+ }
+ else if (!PyErr_Occurred()) {
+ PyErr_Format(PyExc_LookupError, "unknown error handler name '%.400s'", name);
+ }
+ return handler;
+}
+
+static void wrong_exception_type(PyObject *exc)
+{
+ PyErr_Format(PyExc_TypeError,
+ "don't know how to handle %.200s in error callback",
+ Py_TYPE(exc)->tp_name);
+}
+
+PyObject *PyCodec_StrictErrors(PyObject *exc)
+{
+ if (PyExceptionInstance_Check(exc))
+ PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
+ else
+ PyErr_SetString(PyExc_TypeError, "codec must pass exception instance");
+ return NULL;
+}
+
+
+PyObject *PyCodec_IgnoreErrors(PyObject *exc)
+{
+ Py_ssize_t end;
+
+ if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) {
+ if (PyUnicodeEncodeError_GetEnd(exc, &end))
+ return NULL;
+ }
+ else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) {
+ if (PyUnicodeDecodeError_GetEnd(exc, &end))
+ return NULL;
+ }
+ else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeTranslateError)) {
+ if (PyUnicodeTranslateError_GetEnd(exc, &end))
+ return NULL;
+ }
+ else {
+ wrong_exception_type(exc);
+ return NULL;
+ }
+ return Py_BuildValue("(Nn)", PyUnicode_New(0, 0), end);
+}
+
+
+PyObject *PyCodec_ReplaceErrors(PyObject *exc)
+{
+ Py_ssize_t start, end, i, len;
+
+ if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) {
+ PyObject *res;
+ Py_UCS1 *outp;
+ if (PyUnicodeEncodeError_GetStart(exc, &start))
+ return NULL;
+ if (PyUnicodeEncodeError_GetEnd(exc, &end))
+ return NULL;
+ len = end - start;
+ res = PyUnicode_New(len, '?');
+ if (res == NULL)
+ return NULL;
+ assert(PyUnicode_KIND(res) == PyUnicode_1BYTE_KIND);
+ outp = PyUnicode_1BYTE_DATA(res);
+ for (i = 0; i < len; ++i)
+ outp[i] = '?';
+ assert(_PyUnicode_CheckConsistency(res, 1));
+ return Py_BuildValue("(Nn)", res, end);
+ }
+ else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) {
+ if (PyUnicodeDecodeError_GetEnd(exc, &end))
+ return NULL;
+ return Py_BuildValue("(Cn)",
+ (int)Py_UNICODE_REPLACEMENT_CHARACTER,
+ end);
+ }
+ else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeTranslateError)) {
+ PyObject *res;
+ Py_UCS2 *outp;
+ if (PyUnicodeTranslateError_GetStart(exc, &start))
+ return NULL;
+ if (PyUnicodeTranslateError_GetEnd(exc, &end))
+ return NULL;
+ len = end - start;
+ res = PyUnicode_New(len, Py_UNICODE_REPLACEMENT_CHARACTER);
+ if (res == NULL)
+ return NULL;
+ assert(PyUnicode_KIND(res) == PyUnicode_2BYTE_KIND);
+ outp = PyUnicode_2BYTE_DATA(res);
+ for (i = 0; i < len; i++)
+ outp[i] = Py_UNICODE_REPLACEMENT_CHARACTER;
+ assert(_PyUnicode_CheckConsistency(res, 1));
+ return Py_BuildValue("(Nn)", res, end);
+ }
+ else {
+ wrong_exception_type(exc);
+ return NULL;
+ }
+}
+
+PyObject *PyCodec_XMLCharRefReplaceErrors(PyObject *exc)
+{
+ if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) {
+ PyObject *restuple;
+ PyObject *object;
+ Py_ssize_t i;
+ Py_ssize_t start;
+ Py_ssize_t end;
+ PyObject *res;
+ Py_UCS1 *outp;
+ Py_ssize_t ressize;
+ Py_UCS4 ch;
+ if (PyUnicodeEncodeError_GetStart(exc, &start))
+ return NULL;
+ if (PyUnicodeEncodeError_GetEnd(exc, &end))
+ return NULL;
+ if (!(object = PyUnicodeEncodeError_GetObject(exc)))
+ return NULL;
+ if (end - start > PY_SSIZE_T_MAX / (2+7+1))
+ end = start + PY_SSIZE_T_MAX / (2+7+1);
+ for (i = start, ressize = 0; i < end; ++i) {
+ /* object is guaranteed to be "ready" */
+ ch = PyUnicode_READ_CHAR(object, i);
+ if (ch<10)
+ ressize += 2+1+1;
+ else if (ch<100)
+ ressize += 2+2+1;
+ else if (ch<1000)
+ ressize += 2+3+1;
+ else if (ch<10000)
+ ressize += 2+4+1;
+ else if (ch<100000)
+ ressize += 2+5+1;
+ else if (ch<1000000)
+ ressize += 2+6+1;
+ else
+ ressize += 2+7+1;
+ }
+ /* allocate replacement */
+ res = PyUnicode_New(ressize, 127);
+ if (res == NULL) {
+ Py_DECREF(object);
+ return NULL;
+ }
+ outp = PyUnicode_1BYTE_DATA(res);
+ /* generate replacement */
+ for (i = start; i < end; ++i) {
+ int digits;
+ int base;
+ ch = PyUnicode_READ_CHAR(object, i);
+ *outp++ = '&';
+ *outp++ = '#';
+ if (ch<10) {
+ digits = 1;
+ base = 1;
+ }
+ else if (ch<100) {
+ digits = 2;
+ base = 10;
+ }
+ else if (ch<1000) {
+ digits = 3;
+ base = 100;
+ }
+ else if (ch<10000) {
+ digits = 4;
+ base = 1000;
+ }
+ else if (ch<100000) {
+ digits = 5;
+ base = 10000;
+ }
+ else if (ch<1000000) {
+ digits = 6;
+ base = 100000;
+ }
+ else {
+ digits = 7;
+ base = 1000000;
+ }
+ while (digits-->0) {
+ *outp++ = '0' + ch/base;
+ ch %= base;
+ base /= 10;
+ }
+ *outp++ = ';';
+ }
+ assert(_PyUnicode_CheckConsistency(res, 1));
+ restuple = Py_BuildValue("(Nn)", res, end);
+ Py_DECREF(object);
+ return restuple;
+ }
+ else {
+ wrong_exception_type(exc);
+ return NULL;
+ }
+}
+
+PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc)
+{
+ PyObject *object;
+ Py_ssize_t i;
+ Py_ssize_t start;
+ Py_ssize_t end;
+ PyObject *res;
+ Py_UCS1 *outp;
+ int ressize;
+ Py_UCS4 c;
+
+ if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) {
+ const unsigned char *p;
+ if (PyUnicodeDecodeError_GetStart(exc, &start))
+ return NULL;
+ if (PyUnicodeDecodeError_GetEnd(exc, &end))
+ return NULL;
+ if (!(object = PyUnicodeDecodeError_GetObject(exc)))
+ return NULL;
+ p = (const unsigned char*)PyBytes_AS_STRING(object);
+ res = PyUnicode_New(4 * (end - start), 127);
+ if (res == NULL) {
+ Py_DECREF(object);
+ return NULL;
+ }
+ outp = PyUnicode_1BYTE_DATA(res);
+ for (i = start; i < end; i++, outp += 4) {
+ unsigned char c = p[i];
+ outp[0] = '\\';
+ outp[1] = 'x';
+ outp[2] = Py_hexdigits[(c>>4)&0xf];
+ outp[3] = Py_hexdigits[c&0xf];
+ }
+
+ assert(_PyUnicode_CheckConsistency(res, 1));
+ Py_DECREF(object);
+ return Py_BuildValue("(Nn)", res, end);
+ }
+ if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) {
+ if (PyUnicodeEncodeError_GetStart(exc, &start))
+ return NULL;
+ if (PyUnicodeEncodeError_GetEnd(exc, &end))
+ return NULL;
+ if (!(object = PyUnicodeEncodeError_GetObject(exc)))
+ return NULL;
+ }
+ else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeTranslateError)) {
+ if (PyUnicodeTranslateError_GetStart(exc, &start))
+ return NULL;
+ if (PyUnicodeTranslateError_GetEnd(exc, &end))
+ return NULL;
+ if (!(object = PyUnicodeTranslateError_GetObject(exc)))
+ return NULL;
+ }
+ else {
+ wrong_exception_type(exc);
+ return NULL;
+ }
+
+ if (end - start > PY_SSIZE_T_MAX / (1+1+8))
+ end = start + PY_SSIZE_T_MAX / (1+1+8);
+ for (i = start, ressize = 0; i < end; ++i) {
+ /* object is guaranteed to be "ready" */
+ c = PyUnicode_READ_CHAR(object, i);
+ if (c >= 0x10000) {
+ ressize += 1+1+8;
+ }
+ else if (c >= 0x100) {
+ ressize += 1+1+4;
+ }
+ else
+ ressize += 1+1+2;
+ }
+ res = PyUnicode_New(ressize, 127);
+ if (res == NULL) {
+ Py_DECREF(object);
+ return NULL;
+ }
+ outp = PyUnicode_1BYTE_DATA(res);
+ for (i = start; i < end; ++i) {
+ c = PyUnicode_READ_CHAR(object, i);
+ *outp++ = '\\';
+ if (c >= 0x00010000) {
+ *outp++ = 'U';
+ *outp++ = Py_hexdigits[(c>>28)&0xf];
+ *outp++ = Py_hexdigits[(c>>24)&0xf];
+ *outp++ = Py_hexdigits[(c>>20)&0xf];
+ *outp++ = Py_hexdigits[(c>>16)&0xf];
+ *outp++ = Py_hexdigits[(c>>12)&0xf];
+ *outp++ = Py_hexdigits[(c>>8)&0xf];
+ }
+ else if (c >= 0x100) {
+ *outp++ = 'u';
+ *outp++ = Py_hexdigits[(c>>12)&0xf];
+ *outp++ = Py_hexdigits[(c>>8)&0xf];
+ }
+ else
+ *outp++ = 'x';
+ *outp++ = Py_hexdigits[(c>>4)&0xf];
+ *outp++ = Py_hexdigits[c&0xf];
+ }
+
+ assert(_PyUnicode_CheckConsistency(res, 1));
+ Py_DECREF(object);
+ return Py_BuildValue("(Nn)", res, end);
+}
+
+static _PyUnicode_Name_CAPI *ucnhash_CAPI = NULL;
+
+PyObject *PyCodec_NameReplaceErrors(PyObject *exc)
+{
+ if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) {
+ PyObject *restuple;
+ PyObject *object;
+ Py_ssize_t i;
+ Py_ssize_t start;
+ Py_ssize_t end;
+ PyObject *res;
+ Py_UCS1 *outp;
+ Py_ssize_t ressize;
+ int replsize;
+ Py_UCS4 c;
+ char buffer[256]; /* NAME_MAXLEN */
+ if (PyUnicodeEncodeError_GetStart(exc, &start))
+ return NULL;
+ if (PyUnicodeEncodeError_GetEnd(exc, &end))
+ return NULL;
+ if (!(object = PyUnicodeEncodeError_GetObject(exc)))
+ return NULL;
+ if (!ucnhash_CAPI) {
+ /* load the unicode data module */
+ ucnhash_CAPI = (_PyUnicode_Name_CAPI *)PyCapsule_Import(
+ PyUnicodeData_CAPSULE_NAME, 1);
+ if (!ucnhash_CAPI)
+ return NULL;
+ }
+ for (i = start, ressize = 0; i < end; ++i) {
+ /* object is guaranteed to be "ready" */
+ c = PyUnicode_READ_CHAR(object, i);
+ if (ucnhash_CAPI->getname(NULL, c, buffer, sizeof(buffer), 1)) {
+ replsize = 1+1+1+(int)strlen(buffer)+1;
+ }
+ else if (c >= 0x10000) {
+ replsize = 1+1+8;
+ }
+ else if (c >= 0x100) {
+ replsize = 1+1+4;
+ }
+ else
+ replsize = 1+1+2;
+ if (ressize > PY_SSIZE_T_MAX - replsize)
+ break;
+ ressize += replsize;
+ }
+ end = i;
+ res = PyUnicode_New(ressize, 127);
+ if (res==NULL)
+ return NULL;
+ for (i = start, outp = PyUnicode_1BYTE_DATA(res);
+ i < end; ++i) {
+ c = PyUnicode_READ_CHAR(object, i);
+ *outp++ = '\\';
+ if (ucnhash_CAPI->getname(NULL, c, buffer, sizeof(buffer), 1)) {
+ *outp++ = 'N';
+ *outp++ = '{';
+ strcpy((char *)outp, buffer);
+ outp += strlen(buffer);
+ *outp++ = '}';
+ continue;
+ }
+ if (c >= 0x00010000) {
+ *outp++ = 'U';
+ *outp++ = Py_hexdigits[(c>>28)&0xf];
+ *outp++ = Py_hexdigits[(c>>24)&0xf];
+ *outp++ = Py_hexdigits[(c>>20)&0xf];
+ *outp++ = Py_hexdigits[(c>>16)&0xf];
+ *outp++ = Py_hexdigits[(c>>12)&0xf];
+ *outp++ = Py_hexdigits[(c>>8)&0xf];
+ }
+ else if (c >= 0x100) {
+ *outp++ = 'u';
+ *outp++ = Py_hexdigits[(c>>12)&0xf];
+ *outp++ = Py_hexdigits[(c>>8)&0xf];
+ }
+ else
+ *outp++ = 'x';
+ *outp++ = Py_hexdigits[(c>>4)&0xf];
+ *outp++ = Py_hexdigits[c&0xf];
+ }
+
+ assert(outp == PyUnicode_1BYTE_DATA(res) + ressize);
+ assert(_PyUnicode_CheckConsistency(res, 1));
+ restuple = Py_BuildValue("(Nn)", res, end);
+ Py_DECREF(object);
+ return restuple;
+ }
+ else {
+ wrong_exception_type(exc);
+ return NULL;
+ }
+}
+
+#define ENC_UNKNOWN -1
+#define ENC_UTF8 0
+#define ENC_UTF16BE 1
+#define ENC_UTF16LE 2
+#define ENC_UTF32BE 3
+#define ENC_UTF32LE 4
+
+static int
+get_standard_encoding(const char *encoding, int *bytelength)
+{
+ if (Py_TOLOWER(encoding[0]) == 'u' &&
+ Py_TOLOWER(encoding[1]) == 't' &&
+ Py_TOLOWER(encoding[2]) == 'f') {
+ encoding += 3;
+ if (*encoding == '-' || *encoding == '_' )
+ encoding++;
+ if (encoding[0] == '8' && encoding[1] == '\0') {
+ *bytelength = 3;
+ return ENC_UTF8;
+ }
+ else if (encoding[0] == '1' && encoding[1] == '6') {
+ encoding += 2;
+ *bytelength = 2;
+ if (*encoding == '\0') {
+#ifdef WORDS_BIGENDIAN
+ return ENC_UTF16BE;
+#else
+ return ENC_UTF16LE;
+#endif
+ }
+ if (*encoding == '-' || *encoding == '_' )
+ encoding++;
+ if (Py_TOLOWER(encoding[1]) == 'e' && encoding[2] == '\0') {
+ if (Py_TOLOWER(encoding[0]) == 'b')
+ return ENC_UTF16BE;
+ if (Py_TOLOWER(encoding[0]) == 'l')
+ return ENC_UTF16LE;
+ }
+ }
+ else if (encoding[0] == '3' && encoding[1] == '2') {
+ encoding += 2;
+ *bytelength = 4;
+ if (*encoding == '\0') {
+#ifdef WORDS_BIGENDIAN
+ return ENC_UTF32BE;
+#else
+ return ENC_UTF32LE;
+#endif
+ }
+ if (*encoding == '-' || *encoding == '_' )
+ encoding++;
+ if (Py_TOLOWER(encoding[1]) == 'e' && encoding[2] == '\0') {
+ if (Py_TOLOWER(encoding[0]) == 'b')
+ return ENC_UTF32BE;
+ if (Py_TOLOWER(encoding[0]) == 'l')
+ return ENC_UTF32LE;
+ }
+ }
+ }
+ else if (strcmp(encoding, "CP_UTF8") == 0) {
+ *bytelength = 3;
+ return ENC_UTF8;
+ }
+ return ENC_UNKNOWN;
+}
+
+/* This handler is declared static until someone demonstrates
+ a need to call it directly. */
+static PyObject *
+PyCodec_SurrogatePassErrors(PyObject *exc)
+{
+ PyObject *restuple;
+ PyObject *object;
+ PyObject *encode;
+ const char *encoding;
+ int code;
+ int bytelength;
+ Py_ssize_t i;
+ Py_ssize_t start;
+ Py_ssize_t end;
+ PyObject *res;
+
+ if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) {
+ unsigned char *outp;
+ if (PyUnicodeEncodeError_GetStart(exc, &start))
+ return NULL;
+ if (PyUnicodeEncodeError_GetEnd(exc, &end))
+ return NULL;
+ if (!(object = PyUnicodeEncodeError_GetObject(exc)))
+ return NULL;
+ if (!(encode = PyUnicodeEncodeError_GetEncoding(exc))) {
+ Py_DECREF(object);
+ return NULL;
+ }
+ if (!(encoding = PyUnicode_AsUTF8(encode))) {
+ Py_DECREF(object);
+ Py_DECREF(encode);
+ return NULL;
+ }
+ code = get_standard_encoding(encoding, &bytelength);
+ Py_DECREF(encode);
+ if (code == ENC_UNKNOWN) {
+ /* Not supported, fail with original exception */
+ PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
+ Py_DECREF(object);
+ return NULL;
+ }
+
+ if (end - start > PY_SSIZE_T_MAX / bytelength)
+ end = start + PY_SSIZE_T_MAX / bytelength;
+ res = PyBytes_FromStringAndSize(NULL, bytelength*(end-start));
+ if (!res) {
+ Py_DECREF(object);
+ return NULL;
+ }
+ outp = (unsigned char*)PyBytes_AsString(res);
+ for (i = start; i < end; i++) {
+ /* object is guaranteed to be "ready" */
+ Py_UCS4 ch = PyUnicode_READ_CHAR(object, i);
+ if (!Py_UNICODE_IS_SURROGATE(ch)) {
+ /* Not a surrogate, fail with original exception */
+ PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
+ Py_DECREF(res);
+ Py_DECREF(object);
+ return NULL;
+ }
+ switch (code) {
+ case ENC_UTF8:
+ *outp++ = (unsigned char)(0xe0 | (ch >> 12));
+ *outp++ = (unsigned char)(0x80 | ((ch >> 6) & 0x3f));
+ *outp++ = (unsigned char)(0x80 | (ch & 0x3f));
+ break;
+ case ENC_UTF16LE:
+ *outp++ = (unsigned char) ch;
+ *outp++ = (unsigned char)(ch >> 8);
+ break;
+ case ENC_UTF16BE:
+ *outp++ = (unsigned char)(ch >> 8);
+ *outp++ = (unsigned char) ch;
+ break;
+ case ENC_UTF32LE:
+ *outp++ = (unsigned char) ch;
+ *outp++ = (unsigned char)(ch >> 8);
+ *outp++ = (unsigned char)(ch >> 16);
+ *outp++ = (unsigned char)(ch >> 24);
+ break;
+ case ENC_UTF32BE:
+ *outp++ = (unsigned char)(ch >> 24);
+ *outp++ = (unsigned char)(ch >> 16);
+ *outp++ = (unsigned char)(ch >> 8);
+ *outp++ = (unsigned char) ch;
+ break;
+ }
+ }
+ restuple = Py_BuildValue("(On)", res, end);
+ Py_DECREF(res);
+ Py_DECREF(object);
+ return restuple;
+ }
+ else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) {
+ const unsigned char *p;
+ Py_UCS4 ch = 0;
+ if (PyUnicodeDecodeError_GetStart(exc, &start))
+ return NULL;
+ if (PyUnicodeDecodeError_GetEnd(exc, &end))
+ return NULL;
+ if (!(object = PyUnicodeDecodeError_GetObject(exc)))
+ return NULL;
+ p = (const unsigned char*)PyBytes_AS_STRING(object);
+ if (!(encode = PyUnicodeDecodeError_GetEncoding(exc))) {
+ Py_DECREF(object);
+ return NULL;
+ }
+ if (!(encoding = PyUnicode_AsUTF8(encode))) {
+ Py_DECREF(object);
+ Py_DECREF(encode);
+ return NULL;
+ }
+ code = get_standard_encoding(encoding, &bytelength);
+ Py_DECREF(encode);
+ if (code == ENC_UNKNOWN) {
+ /* Not supported, fail with original exception */
+ PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
+ Py_DECREF(object);
+ return NULL;
+ }
+
+ /* Try decoding a single surrogate character. If
+ there are more, let the codec call us again. */
+ p += start;
+ if (PyBytes_GET_SIZE(object) - start >= bytelength) {
+ switch (code) {
+ case ENC_UTF8:
+ if ((p[0] & 0xf0) == 0xe0 &&
+ (p[1] & 0xc0) == 0x80 &&
+ (p[2] & 0xc0) == 0x80) {
+ /* it's a three-byte code */
+ ch = ((p[0] & 0x0f) << 12) + ((p[1] & 0x3f) << 6) + (p[2] & 0x3f);
+ }
+ break;
+ case ENC_UTF16LE:
+ ch = p[1] << 8 | p[0];
+ break;
+ case ENC_UTF16BE:
+ ch = p[0] << 8 | p[1];
+ break;
+ case ENC_UTF32LE:
+ ch = (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
+ break;
+ case ENC_UTF32BE:
+ ch = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+ break;
+ }
+ }
+
+ Py_DECREF(object);
+ if (!Py_UNICODE_IS_SURROGATE(ch)) {
+ /* it's not a surrogate - fail */
+ PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
+ return NULL;
+ }
+ res = PyUnicode_FromOrdinal(ch);
+ if (res == NULL)
+ return NULL;
+ return Py_BuildValue("(Nn)", res, start + bytelength);
+ }
+ else {
+ wrong_exception_type(exc);
+ return NULL;
+ }
+}
+
+static PyObject *
+PyCodec_SurrogateEscapeErrors(PyObject *exc)
+{
+ PyObject *restuple;
+ PyObject *object;
+ Py_ssize_t i;
+ Py_ssize_t start;
+ Py_ssize_t end;
+ PyObject *res;
+
+ if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) {
+ char *outp;
+ if (PyUnicodeEncodeError_GetStart(exc, &start))
+ return NULL;
+ if (PyUnicodeEncodeError_GetEnd(exc, &end))
+ return NULL;
+ if (!(object = PyUnicodeEncodeError_GetObject(exc)))
+ return NULL;
+ res = PyBytes_FromStringAndSize(NULL, end-start);
+ if (!res) {
+ Py_DECREF(object);
+ return NULL;
+ }
+ outp = PyBytes_AsString(res);
+ for (i = start; i < end; i++) {
+ /* object is guaranteed to be "ready" */
+ Py_UCS4 ch = PyUnicode_READ_CHAR(object, i);
+ if (ch < 0xdc80 || ch > 0xdcff) {
+ /* Not a UTF-8b surrogate, fail with original exception */
+ PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
+ Py_DECREF(res);
+ Py_DECREF(object);
+ return NULL;
+ }
+ *outp++ = ch - 0xdc00;
+ }
+ restuple = Py_BuildValue("(On)", res, end);
+ Py_DECREF(res);
+ Py_DECREF(object);
+ return restuple;
+ }
+ else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) {
+ PyObject *str;
+ const unsigned char *p;
+ Py_UCS2 ch[4]; /* decode up to 4 bad bytes. */
+ int consumed = 0;
+ if (PyUnicodeDecodeError_GetStart(exc, &start))
+ return NULL;
+ if (PyUnicodeDecodeError_GetEnd(exc, &end))
+ return NULL;
+ if (!(object = PyUnicodeDecodeError_GetObject(exc)))
+ return NULL;
+ p = (const unsigned char*)PyBytes_AS_STRING(object);
+ while (consumed < 4 && consumed < end-start) {
+ /* Refuse to escape ASCII bytes. */
+ if (p[start+consumed] < 128)
+ break;
+ ch[consumed] = 0xdc00 + p[start+consumed];
+ consumed++;
+ }
+ Py_DECREF(object);
+ if (!consumed) {
+ /* codec complained about ASCII byte. */
+ PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
+ return NULL;
+ }
+ str = PyUnicode_FromKindAndData(PyUnicode_2BYTE_KIND, ch, consumed);
+ if (str == NULL)
+ return NULL;
+ return Py_BuildValue("(Nn)", str, start+consumed);
+ }
+ else {
+ wrong_exception_type(exc);
+ return NULL;
+ }
+}
+
+
+static PyObject *strict_errors(PyObject *self, PyObject *exc)
+{
+ return PyCodec_StrictErrors(exc);
+}
+
+
+static PyObject *ignore_errors(PyObject *self, PyObject *exc)
+{
+ return PyCodec_IgnoreErrors(exc);
+}
+
+
+static PyObject *replace_errors(PyObject *self, PyObject *exc)
+{
+ return PyCodec_ReplaceErrors(exc);
+}
+
+
+static PyObject *xmlcharrefreplace_errors(PyObject *self, PyObject *exc)
+{
+ return PyCodec_XMLCharRefReplaceErrors(exc);
+}
+
+
+static PyObject *backslashreplace_errors(PyObject *self, PyObject *exc)
+{
+ return PyCodec_BackslashReplaceErrors(exc);
+}
+
+static PyObject *namereplace_errors(PyObject *self, PyObject *exc)
+{
+ return PyCodec_NameReplaceErrors(exc);
+}
+
+static PyObject *surrogatepass_errors(PyObject *self, PyObject *exc)
+{
+ return PyCodec_SurrogatePassErrors(exc);
+}
+
+static PyObject *surrogateescape_errors(PyObject *self, PyObject *exc)
+{
+ return PyCodec_SurrogateEscapeErrors(exc);
+}
+
+static int _PyCodecRegistry_Init(void)
+{
+ static struct {
+ const char *name;
+ PyMethodDef def;
+ } methods[] =
+ {
+ {
+ "strict",
+ {
+ "strict_errors",
+ strict_errors,
+ METH_O,
+ PyDoc_STR("Implements the 'strict' error handling, which "
+ "raises a UnicodeError on coding errors.")
+ }
+ },
+ {
+ "ignore",
+ {
+ "ignore_errors",
+ ignore_errors,
+ METH_O,
+ PyDoc_STR("Implements the 'ignore' error handling, which "
+ "ignores malformed data and continues.")
+ }
+ },
+ {
+ "replace",
+ {
+ "replace_errors",
+ replace_errors,
+ METH_O,
+ PyDoc_STR("Implements the 'replace' error handling, which "
+ "replaces malformed data with a replacement marker.")
+ }
+ },
+ {
+ "xmlcharrefreplace",
+ {
+ "xmlcharrefreplace_errors",
+ xmlcharrefreplace_errors,
+ METH_O,
+ PyDoc_STR("Implements the 'xmlcharrefreplace' error handling, "
+ "which replaces an unencodable character with the "
+ "appropriate XML character reference.")
+ }
+ },
+ {
+ "backslashreplace",
+ {
+ "backslashreplace_errors",
+ backslashreplace_errors,
+ METH_O,
+ PyDoc_STR("Implements the 'backslashreplace' error handling, "
+ "which replaces malformed data with a backslashed "
+ "escape sequence.")
+ }
+ },
+ {
+ "namereplace",
+ {
+ "namereplace_errors",
+ namereplace_errors,
+ METH_O,
+ PyDoc_STR("Implements the 'namereplace' error handling, "
+ "which replaces an unencodable character with a "
+ "\\N{...} escape sequence.")
+ }
+ },
+ {
+ "surrogatepass",
+ {
+ "surrogatepass",
+ surrogatepass_errors,
+ METH_O
+ }
+ },
+ {
+ "surrogateescape",
+ {
+ "surrogateescape",
+ surrogateescape_errors,
+ METH_O
+ }
+ }
+ };
+
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ PyObject *mod;
+
+ if (interp->codec_search_path != NULL)
+ return 0;
+
+ interp->codec_search_path = PyList_New(0);
+ if (interp->codec_search_path == NULL) {
+ return -1;
+ }
+
+ interp->codec_search_cache = PyDict_New();
+ if (interp->codec_search_cache == NULL) {
+ return -1;
+ }
+
+ interp->codec_error_registry = PyDict_New();
+ if (interp->codec_error_registry == NULL) {
+ return -1;
+ }
+
+ for (size_t i = 0; i < Py_ARRAY_LENGTH(methods); ++i) {
+ PyObject *func = PyCFunction_NewEx(&methods[i].def, NULL, NULL);
+ if (!func) {
+ return -1;
+ }
+
+ int res = PyCodec_RegisterError(methods[i].name, func);
+ Py_DECREF(func);
+ if (res) {
+ return -1;
+ }
+ }
+
+ mod = PyImport_ImportModuleNoBlock("encodings");
+ if (mod == NULL) {
+ return -1;
+ }
+ Py_DECREF(mod);
+ interp->codecs_initialized = 1;
+ return 0;
+}
diff --git a/contrib/tools/python3/src/Python/compile.c b/contrib/tools/python3/src/Python/compile.c
new file mode 100644
index 00000000000..f426050ccef
--- /dev/null
+++ b/contrib/tools/python3/src/Python/compile.c
@@ -0,0 +1,6083 @@
+/*
+ * This file compiles an abstract syntax tree (AST) into Python bytecode.
+ *
+ * The primary entry point is PyAST_Compile(), which returns a
+ * PyCodeObject. The compiler makes several passes to build the code
+ * object:
+ * 1. Checks for future statements. See future.c
+ * 2. Builds a symbol table. See symtable.c.
+ * 3. Generate code for basic blocks. See compiler_mod() in this file.
+ * 4. Assemble the basic blocks into final code. See assemble() in
+ * this file.
+ * 5. Optimize the byte code (peephole optimizations). See peephole.c
+ *
+ * Note that compiler_mod() suggests module, but the module ast type
+ * (mod_ty) has cases for expressions and interactive statements.
+ *
+ * CAUTION: The VISIT_* macros abort the current function when they
+ * encounter a problem. So don't invoke them when there is memory
+ * which needs to be released. Code blocks are OK, as the compiler
+ * structure takes care of releasing those. Use the arena to manage
+ * objects.
+ */
+
+#include "Python.h"
+
+#include "Python-ast.h"
+#include "ast.h"
+#include "code.h"
+#include "symtable.h"
+#include "opcode.h"
+#include "wordcode_helpers.h"
+
+#define DEFAULT_BLOCK_SIZE 16
+#define DEFAULT_BLOCKS 8
+#define DEFAULT_CODE_SIZE 128
+#define DEFAULT_LNOTAB_SIZE 16
+
+#define COMP_GENEXP 0
+#define COMP_LISTCOMP 1
+#define COMP_SETCOMP 2
+#define COMP_DICTCOMP 3
+
+#define IS_TOP_LEVEL_AWAIT(c) ( \
+ (c->c_flags->cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT) \
+ && (c->u->u_ste->ste_type == ModuleBlock))
+
+struct instr {
+ unsigned i_jabs : 1;
+ unsigned i_jrel : 1;
+ unsigned char i_opcode;
+ int i_oparg;
+ struct basicblock_ *i_target; /* target block (if jump instruction) */
+ int i_lineno;
+};
+
+typedef struct basicblock_ {
+ /* Each basicblock in a compilation unit is linked via b_list in the
+ reverse order that the block are allocated. b_list points to the next
+ block, not to be confused with b_next, which is next by control flow. */
+ struct basicblock_ *b_list;
+ /* number of instructions used */
+ int b_iused;
+ /* length of instruction array (b_instr) */
+ int b_ialloc;
+ /* pointer to an array of instructions, initially NULL */
+ struct instr *b_instr;
+ /* If b_next is non-NULL, it is a pointer to the next
+ block reached by normal control flow. */
+ struct basicblock_ *b_next;
+ /* b_seen is used to perform a DFS of basicblocks. */
+ unsigned b_seen : 1;
+ /* b_return is true if a RETURN_VALUE opcode is inserted. */
+ unsigned b_return : 1;
+ /* depth of stack upon entry of block, computed by stackdepth() */
+ int b_startdepth;
+ /* instruction offset for block, computed by assemble_jump_offsets() */
+ int b_offset;
+} basicblock;
+
+/* fblockinfo tracks the current frame block.
+
+A frame block is used to handle loops, try/except, and try/finally.
+It's called a frame block to distinguish it from a basic block in the
+compiler IR.
+*/
+
+enum fblocktype { WHILE_LOOP, FOR_LOOP, TRY_EXCEPT, FINALLY_TRY, FINALLY_END,
+ WITH, ASYNC_WITH, HANDLER_CLEANUP, POP_VALUE, EXCEPTION_HANDLER };
+
+struct fblockinfo {
+ enum fblocktype fb_type;
+ basicblock *fb_block;
+ /* (optional) type-specific exit or cleanup block */
+ basicblock *fb_exit;
+ /* (optional) additional information required for unwinding */
+ void *fb_datum;
+};
+
+enum {
+ COMPILER_SCOPE_MODULE,
+ COMPILER_SCOPE_CLASS,
+ COMPILER_SCOPE_FUNCTION,
+ COMPILER_SCOPE_ASYNC_FUNCTION,
+ COMPILER_SCOPE_LAMBDA,
+ COMPILER_SCOPE_COMPREHENSION,
+};
+
+/* The following items change on entry and exit of code blocks.
+ They must be saved and restored when returning to a block.
+*/
+struct compiler_unit {
+ PySTEntryObject *u_ste;
+
+ PyObject *u_name;
+ PyObject *u_qualname; /* dot-separated qualified name (lazy) */
+ int u_scope_type;
+
+ /* The following fields are dicts that map objects to
+ the index of them in co_XXX. The index is used as
+ the argument for opcodes that refer to those collections.
+ */
+ PyObject *u_consts; /* all constants */
+ PyObject *u_names; /* all names */
+ PyObject *u_varnames; /* local variables */
+ PyObject *u_cellvars; /* cell variables */
+ PyObject *u_freevars; /* free variables */
+
+ PyObject *u_private; /* for private name mangling */
+
+ Py_ssize_t u_argcount; /* number of arguments for block */
+ Py_ssize_t u_posonlyargcount; /* number of positional only arguments for block */
+ Py_ssize_t u_kwonlyargcount; /* number of keyword only arguments for block */
+ /* Pointer to the most recently allocated block. By following b_list
+ members, you can reach all early allocated blocks. */
+ basicblock *u_blocks;
+ basicblock *u_curblock; /* pointer to current block */
+
+ int u_nfblocks;
+ struct fblockinfo u_fblock[CO_MAXBLOCKS];
+
+ int u_firstlineno; /* the first lineno of the block */
+ int u_lineno; /* the lineno for the current stmt */
+ int u_col_offset; /* the offset of the current stmt */
+};
+
+/* This struct captures the global state of a compilation.
+
+The u pointer points to the current compilation unit, while units
+for enclosing blocks are stored in c_stack. The u and c_stack are
+managed by compiler_enter_scope() and compiler_exit_scope().
+
+Note that we don't track recursion levels during compilation - the
+task of detecting and rejecting excessive levels of nesting is
+handled by the symbol analysis pass.
+
+*/
+
+struct compiler {
+ PyObject *c_filename;
+ struct symtable *c_st;
+ PyFutureFeatures *c_future; /* pointer to module's __future__ */
+ PyCompilerFlags *c_flags;
+
+ int c_optimize; /* optimization level */
+ int c_interactive; /* true if in interactive mode */
+ int c_nestlevel;
+ int c_do_not_emit_bytecode; /* The compiler won't emit any bytecode
+ if this value is different from zero.
+ This can be used to temporarily visit
+ nodes without emitting bytecode to
+ check only errors. */
+
+ PyObject *c_const_cache; /* Python dict holding all constants,
+ including names tuple */
+ struct compiler_unit *u; /* compiler state for current block */
+ PyObject *c_stack; /* Python list holding compiler_unit ptrs */
+ PyArena *c_arena; /* pointer to memory allocation arena */
+};
+
+static int compiler_enter_scope(struct compiler *, identifier, int, void *, int);
+static void compiler_free(struct compiler *);
+static basicblock *compiler_new_block(struct compiler *);
+static int compiler_next_instr(basicblock *);
+static int compiler_addop(struct compiler *, int);
+static int compiler_addop_i(struct compiler *, int, Py_ssize_t);
+static int compiler_addop_j(struct compiler *, int, basicblock *, int);
+static int compiler_error(struct compiler *, const char *);
+static int compiler_warn(struct compiler *, const char *, ...);
+static int compiler_nameop(struct compiler *, identifier, expr_context_ty);
+
+static PyCodeObject *compiler_mod(struct compiler *, mod_ty);
+static int compiler_visit_stmt(struct compiler *, stmt_ty);
+static int compiler_visit_keyword(struct compiler *, keyword_ty);
+static int compiler_visit_expr(struct compiler *, expr_ty);
+static int compiler_augassign(struct compiler *, stmt_ty);
+static int compiler_annassign(struct compiler *, stmt_ty);
+static int compiler_subscript(struct compiler *, expr_ty);
+static int compiler_slice(struct compiler *, expr_ty);
+
+static int inplace_binop(operator_ty);
+static int are_all_items_const(asdl_seq *, Py_ssize_t, Py_ssize_t);
+static int expr_constant(expr_ty);
+
+static int compiler_with(struct compiler *, stmt_ty, int);
+static int compiler_async_with(struct compiler *, stmt_ty, int);
+static int compiler_async_for(struct compiler *, stmt_ty);
+static int compiler_call_helper(struct compiler *c, int n,
+ asdl_seq *args,
+ asdl_seq *keywords);
+static int compiler_try_except(struct compiler *, stmt_ty);
+static int compiler_set_qualname(struct compiler *);
+
+static int compiler_sync_comprehension_generator(
+ struct compiler *c,
+ asdl_seq *generators, int gen_index,
+ int depth,
+ expr_ty elt, expr_ty val, int type);
+
+static int compiler_async_comprehension_generator(
+ struct compiler *c,
+ asdl_seq *generators, int gen_index,
+ int depth,
+ expr_ty elt, expr_ty val, int type);
+
+static PyCodeObject *assemble(struct compiler *, int addNone);
+static PyObject *__doc__, *__annotations__;
+
+#define CAPSULE_NAME "compile.c compiler unit"
+
+PyObject *
+_Py_Mangle(PyObject *privateobj, PyObject *ident)
+{
+ /* Name mangling: __private becomes _classname__private.
+ This is independent from how the name is used. */
+ PyObject *result;
+ size_t nlen, plen, ipriv;
+ Py_UCS4 maxchar;
+ if (privateobj == NULL || !PyUnicode_Check(privateobj) ||
+ PyUnicode_READ_CHAR(ident, 0) != '_' ||
+ PyUnicode_READ_CHAR(ident, 1) != '_') {
+ Py_INCREF(ident);
+ return ident;
+ }
+ nlen = PyUnicode_GET_LENGTH(ident);
+ plen = PyUnicode_GET_LENGTH(privateobj);
+ /* Don't mangle __id__ or names with dots.
+
+ The only time a name with a dot can occur is when
+ we are compiling an import statement that has a
+ package name.
+
+ TODO(jhylton): Decide whether we want to support
+ mangling of the module name, e.g. __M.X.
+ */
+ if ((PyUnicode_READ_CHAR(ident, nlen-1) == '_' &&
+ PyUnicode_READ_CHAR(ident, nlen-2) == '_') ||
+ PyUnicode_FindChar(ident, '.', 0, nlen, 1) != -1) {
+ Py_INCREF(ident);
+ return ident; /* Don't mangle __whatever__ */
+ }
+ /* Strip leading underscores from class name */
+ ipriv = 0;
+ while (PyUnicode_READ_CHAR(privateobj, ipriv) == '_')
+ ipriv++;
+ if (ipriv == plen) {
+ Py_INCREF(ident);
+ return ident; /* Don't mangle if class is just underscores */
+ }
+ plen -= ipriv;
+
+ if (plen + nlen >= PY_SSIZE_T_MAX - 1) {
+ PyErr_SetString(PyExc_OverflowError,
+ "private identifier too large to be mangled");
+ return NULL;
+ }
+
+ maxchar = PyUnicode_MAX_CHAR_VALUE(ident);
+ if (PyUnicode_MAX_CHAR_VALUE(privateobj) > maxchar)
+ maxchar = PyUnicode_MAX_CHAR_VALUE(privateobj);
+
+ result = PyUnicode_New(1 + nlen + plen, maxchar);
+ if (!result)
+ return 0;
+ /* ident = "_" + priv[ipriv:] + ident # i.e. 1+plen+nlen bytes */
+ PyUnicode_WRITE(PyUnicode_KIND(result), PyUnicode_DATA(result), 0, '_');
+ if (PyUnicode_CopyCharacters(result, 1, privateobj, ipriv, plen) < 0) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ if (PyUnicode_CopyCharacters(result, plen+1, ident, 0, nlen) < 0) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ assert(_PyUnicode_CheckConsistency(result, 1));
+ return result;
+}
+
+static int
+compiler_init(struct compiler *c)
+{
+ memset(c, 0, sizeof(struct compiler));
+
+ c->c_const_cache = PyDict_New();
+ if (!c->c_const_cache) {
+ return 0;
+ }
+
+ c->c_stack = PyList_New(0);
+ if (!c->c_stack) {
+ Py_CLEAR(c->c_const_cache);
+ return 0;
+ }
+
+ return 1;
+}
+
+PyCodeObject *
+PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags,
+ int optimize, PyArena *arena)
+{
+ struct compiler c;
+ PyCodeObject *co = NULL;
+ PyCompilerFlags local_flags = _PyCompilerFlags_INIT;
+ int merged;
+
+ if (!__doc__) {
+ __doc__ = PyUnicode_InternFromString("__doc__");
+ if (!__doc__)
+ return NULL;
+ }
+ if (!__annotations__) {
+ __annotations__ = PyUnicode_InternFromString("__annotations__");
+ if (!__annotations__)
+ return NULL;
+ }
+ if (!compiler_init(&c))
+ return NULL;
+ Py_INCREF(filename);
+ c.c_filename = filename;
+ c.c_arena = arena;
+ c.c_future = PyFuture_FromASTObject(mod, filename);
+ if (c.c_future == NULL)
+ goto finally;
+ if (!flags) {
+ flags = &local_flags;
+ }
+ merged = c.c_future->ff_features | flags->cf_flags;
+ c.c_future->ff_features = merged;
+ flags->cf_flags = merged;
+ c.c_flags = flags;
+ c.c_optimize = (optimize == -1) ? _Py_GetConfig()->optimization_level : optimize;
+ c.c_nestlevel = 0;
+ c.c_do_not_emit_bytecode = 0;
+
+ _PyASTOptimizeState state;
+ state.optimize = c.c_optimize;
+ state.ff_features = merged;
+
+ if (!_PyAST_Optimize(mod, arena, &state)) {
+ goto finally;
+ }
+
+ c.c_st = PySymtable_BuildObject(mod, filename, c.c_future);
+ if (c.c_st == NULL) {
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_SystemError, "no symtable");
+ goto finally;
+ }
+
+ co = compiler_mod(&c, mod);
+
+ finally:
+ compiler_free(&c);
+ assert(co || PyErr_Occurred());
+ return co;
+}
+
+PyCodeObject *
+PyAST_CompileEx(mod_ty mod, const char *filename_str, PyCompilerFlags *flags,
+ int optimize, PyArena *arena)
+{
+ PyObject *filename;
+ PyCodeObject *co;
+ filename = PyUnicode_DecodeFSDefault(filename_str);
+ if (filename == NULL)
+ return NULL;
+ co = PyAST_CompileObject(mod, filename, flags, optimize, arena);
+ Py_DECREF(filename);
+ return co;
+
+}
+
+PyCodeObject *
+PyNode_Compile(struct _node *n, const char *filename)
+{
+ PyCodeObject *co = NULL;
+ mod_ty mod;
+ PyArena *arena = PyArena_New();
+ if (!arena)
+ return NULL;
+ mod = PyAST_FromNode(n, NULL, filename, arena);
+ if (mod)
+ co = PyAST_Compile(mod, filename, NULL, arena);
+ PyArena_Free(arena);
+ return co;
+}
+
+static void
+compiler_free(struct compiler *c)
+{
+ if (c->c_st)
+ PySymtable_Free(c->c_st);
+ if (c->c_future)
+ PyObject_Free(c->c_future);
+ Py_XDECREF(c->c_filename);
+ Py_DECREF(c->c_const_cache);
+ Py_DECREF(c->c_stack);
+}
+
+static PyObject *
+list2dict(PyObject *list)
+{
+ Py_ssize_t i, n;
+ PyObject *v, *k;
+ PyObject *dict = PyDict_New();
+ if (!dict) return NULL;
+
+ n = PyList_Size(list);
+ for (i = 0; i < n; i++) {
+ v = PyLong_FromSsize_t(i);
+ if (!v) {
+ Py_DECREF(dict);
+ return NULL;
+ }
+ k = PyList_GET_ITEM(list, i);
+ if (PyDict_SetItem(dict, k, v) < 0) {
+ Py_DECREF(v);
+ Py_DECREF(dict);
+ return NULL;
+ }
+ Py_DECREF(v);
+ }
+ return dict;
+}
+
+/* Return new dict containing names from src that match scope(s).
+
+src is a symbol table dictionary. If the scope of a name matches
+either scope_type or flag is set, insert it into the new dict. The
+values are integers, starting at offset and increasing by one for
+each key.
+*/
+
+static PyObject *
+dictbytype(PyObject *src, int scope_type, int flag, Py_ssize_t offset)
+{
+ Py_ssize_t i = offset, scope, num_keys, key_i;
+ PyObject *k, *v, *dest = PyDict_New();
+ PyObject *sorted_keys;
+
+ assert(offset >= 0);
+ if (dest == NULL)
+ return NULL;
+
+ /* Sort the keys so that we have a deterministic order on the indexes
+ saved in the returned dictionary. These indexes are used as indexes
+ into the free and cell var storage. Therefore if they aren't
+ deterministic, then the generated bytecode is not deterministic.
+ */
+ sorted_keys = PyDict_Keys(src);
+ if (sorted_keys == NULL)
+ return NULL;
+ if (PyList_Sort(sorted_keys) != 0) {
+ Py_DECREF(sorted_keys);
+ return NULL;
+ }
+ num_keys = PyList_GET_SIZE(sorted_keys);
+
+ for (key_i = 0; key_i < num_keys; key_i++) {
+ /* XXX this should probably be a macro in symtable.h */
+ long vi;
+ k = PyList_GET_ITEM(sorted_keys, key_i);
+ v = PyDict_GetItem(src, k);
+ assert(PyLong_Check(v));
+ vi = PyLong_AS_LONG(v);
+ scope = (vi >> SCOPE_OFFSET) & SCOPE_MASK;
+
+ if (scope == scope_type || vi & flag) {
+ PyObject *item = PyLong_FromSsize_t(i);
+ if (item == NULL) {
+ Py_DECREF(sorted_keys);
+ Py_DECREF(dest);
+ return NULL;
+ }
+ i++;
+ if (PyDict_SetItem(dest, k, item) < 0) {
+ Py_DECREF(sorted_keys);
+ Py_DECREF(item);
+ Py_DECREF(dest);
+ return NULL;
+ }
+ Py_DECREF(item);
+ }
+ }
+ Py_DECREF(sorted_keys);
+ return dest;
+}
+
+static void
+compiler_unit_check(struct compiler_unit *u)
+{
+ basicblock *block;
+ for (block = u->u_blocks; block != NULL; block = block->b_list) {
+ assert((uintptr_t)block != 0xcbcbcbcbU);
+ assert((uintptr_t)block != 0xfbfbfbfbU);
+ assert((uintptr_t)block != 0xdbdbdbdbU);
+ if (block->b_instr != NULL) {
+ assert(block->b_ialloc > 0);
+ assert(block->b_iused > 0);
+ assert(block->b_ialloc >= block->b_iused);
+ }
+ else {
+ assert (block->b_iused == 0);
+ assert (block->b_ialloc == 0);
+ }
+ }
+}
+
+static void
+compiler_unit_free(struct compiler_unit *u)
+{
+ basicblock *b, *next;
+
+ compiler_unit_check(u);
+ b = u->u_blocks;
+ while (b != NULL) {
+ if (b->b_instr)
+ PyObject_Free((void *)b->b_instr);
+ next = b->b_list;
+ PyObject_Free((void *)b);
+ b = next;
+ }
+ Py_CLEAR(u->u_ste);
+ Py_CLEAR(u->u_name);
+ Py_CLEAR(u->u_qualname);
+ Py_CLEAR(u->u_consts);
+ Py_CLEAR(u->u_names);
+ Py_CLEAR(u->u_varnames);
+ Py_CLEAR(u->u_freevars);
+ Py_CLEAR(u->u_cellvars);
+ Py_CLEAR(u->u_private);
+ PyObject_Free(u);
+}
+
+static int
+compiler_enter_scope(struct compiler *c, identifier name,
+ int scope_type, void *key, int lineno)
+{
+ struct compiler_unit *u;
+ basicblock *block;
+
+ u = (struct compiler_unit *)PyObject_Calloc(1, sizeof(
+ struct compiler_unit));
+ if (!u) {
+ PyErr_NoMemory();
+ return 0;
+ }
+ u->u_scope_type = scope_type;
+ u->u_argcount = 0;
+ u->u_posonlyargcount = 0;
+ u->u_kwonlyargcount = 0;
+ u->u_ste = PySymtable_Lookup(c->c_st, key);
+ if (!u->u_ste) {
+ compiler_unit_free(u);
+ return 0;
+ }
+ Py_INCREF(name);
+ u->u_name = name;
+ u->u_varnames = list2dict(u->u_ste->ste_varnames);
+ u->u_cellvars = dictbytype(u->u_ste->ste_symbols, CELL, 0, 0);
+ if (!u->u_varnames || !u->u_cellvars) {
+ compiler_unit_free(u);
+ return 0;
+ }
+ if (u->u_ste->ste_needs_class_closure) {
+ /* Cook up an implicit __class__ cell. */
+ _Py_IDENTIFIER(__class__);
+ PyObject *name;
+ int res;
+ assert(u->u_scope_type == COMPILER_SCOPE_CLASS);
+ assert(PyDict_GET_SIZE(u->u_cellvars) == 0);
+ name = _PyUnicode_FromId(&PyId___class__);
+ if (!name) {
+ compiler_unit_free(u);
+ return 0;
+ }
+ res = PyDict_SetItem(u->u_cellvars, name, _PyLong_Zero);
+ if (res < 0) {
+ compiler_unit_free(u);
+ return 0;
+ }
+ }
+
+ u->u_freevars = dictbytype(u->u_ste->ste_symbols, FREE, DEF_FREE_CLASS,
+ PyDict_GET_SIZE(u->u_cellvars));
+ if (!u->u_freevars) {
+ compiler_unit_free(u);
+ return 0;
+ }
+
+ u->u_blocks = NULL;
+ u->u_nfblocks = 0;
+ u->u_firstlineno = lineno;
+ u->u_lineno = 0;
+ u->u_col_offset = 0;
+ u->u_consts = PyDict_New();
+ if (!u->u_consts) {
+ compiler_unit_free(u);
+ return 0;
+ }
+ u->u_names = PyDict_New();
+ if (!u->u_names) {
+ compiler_unit_free(u);
+ return 0;
+ }
+
+ u->u_private = NULL;
+
+ /* Push the old compiler_unit on the stack. */
+ if (c->u) {
+ PyObject *capsule = PyCapsule_New(c->u, CAPSULE_NAME, NULL);
+ if (!capsule || PyList_Append(c->c_stack, capsule) < 0) {
+ Py_XDECREF(capsule);
+ compiler_unit_free(u);
+ return 0;
+ }
+ Py_DECREF(capsule);
+ u->u_private = c->u->u_private;
+ Py_XINCREF(u->u_private);
+ }
+ c->u = u;
+
+ c->c_nestlevel++;
+
+ block = compiler_new_block(c);
+ if (block == NULL)
+ return 0;
+ c->u->u_curblock = block;
+
+ if (u->u_scope_type != COMPILER_SCOPE_MODULE) {
+ if (!compiler_set_qualname(c))
+ return 0;
+ }
+
+ return 1;
+}
+
+static void
+compiler_exit_scope(struct compiler *c)
+{
+ Py_ssize_t n;
+ PyObject *capsule;
+
+ c->c_nestlevel--;
+ compiler_unit_free(c->u);
+ /* Restore c->u to the parent unit. */
+ n = PyList_GET_SIZE(c->c_stack) - 1;
+ if (n >= 0) {
+ capsule = PyList_GET_ITEM(c->c_stack, n);
+ c->u = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME);
+ assert(c->u);
+ /* we are deleting from a list so this really shouldn't fail */
+ if (PySequence_DelItem(c->c_stack, n) < 0)
+ Py_FatalError("compiler_exit_scope()");
+ compiler_unit_check(c->u);
+ }
+ else
+ c->u = NULL;
+
+}
+
+static int
+compiler_set_qualname(struct compiler *c)
+{
+ _Py_static_string(dot, ".");
+ _Py_static_string(dot_locals, ".<locals>");
+ Py_ssize_t stack_size;
+ struct compiler_unit *u = c->u;
+ PyObject *name, *base, *dot_str, *dot_locals_str;
+
+ base = NULL;
+ stack_size = PyList_GET_SIZE(c->c_stack);
+ assert(stack_size >= 1);
+ if (stack_size > 1) {
+ int scope, force_global = 0;
+ struct compiler_unit *parent;
+ PyObject *mangled, *capsule;
+
+ capsule = PyList_GET_ITEM(c->c_stack, stack_size - 1);
+ parent = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME);
+ assert(parent);
+
+ if (u->u_scope_type == COMPILER_SCOPE_FUNCTION
+ || u->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION
+ || u->u_scope_type == COMPILER_SCOPE_CLASS) {
+ assert(u->u_name);
+ mangled = _Py_Mangle(parent->u_private, u->u_name);
+ if (!mangled)
+ return 0;
+ scope = PyST_GetScope(parent->u_ste, mangled);
+ Py_DECREF(mangled);
+ assert(scope != GLOBAL_IMPLICIT);
+ if (scope == GLOBAL_EXPLICIT)
+ force_global = 1;
+ }
+
+ if (!force_global) {
+ if (parent->u_scope_type == COMPILER_SCOPE_FUNCTION
+ || parent->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION
+ || parent->u_scope_type == COMPILER_SCOPE_LAMBDA) {
+ dot_locals_str = _PyUnicode_FromId(&dot_locals);
+ if (dot_locals_str == NULL)
+ return 0;
+ base = PyUnicode_Concat(parent->u_qualname, dot_locals_str);
+ if (base == NULL)
+ return 0;
+ }
+ else {
+ Py_INCREF(parent->u_qualname);
+ base = parent->u_qualname;
+ }
+ }
+ }
+
+ if (base != NULL) {
+ dot_str = _PyUnicode_FromId(&dot);
+ if (dot_str == NULL) {
+ Py_DECREF(base);
+ return 0;
+ }
+ name = PyUnicode_Concat(base, dot_str);
+ Py_DECREF(base);
+ if (name == NULL)
+ return 0;
+ PyUnicode_Append(&name, u->u_name);
+ if (name == NULL)
+ return 0;
+ }
+ else {
+ Py_INCREF(u->u_name);
+ name = u->u_name;
+ }
+ u->u_qualname = name;
+
+ return 1;
+}
+
+
+/* Allocate a new block and return a pointer to it.
+ Returns NULL on error.
+*/
+
+static basicblock *
+compiler_new_block(struct compiler *c)
+{
+ basicblock *b;
+ struct compiler_unit *u;
+
+ u = c->u;
+ b = (basicblock *)PyObject_Calloc(1, sizeof(basicblock));
+ if (b == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ /* Extend the singly linked list of blocks with new block. */
+ b->b_list = u->u_blocks;
+ u->u_blocks = b;
+ return b;
+}
+
+static basicblock *
+compiler_next_block(struct compiler *c)
+{
+ basicblock *block = compiler_new_block(c);
+ if (block == NULL)
+ return NULL;
+ c->u->u_curblock->b_next = block;
+ c->u->u_curblock = block;
+ return block;
+}
+
+static basicblock *
+compiler_use_next_block(struct compiler *c, basicblock *block)
+{
+ assert(block != NULL);
+ c->u->u_curblock->b_next = block;
+ c->u->u_curblock = block;
+ return block;
+}
+
+/* Returns the offset of the next instruction in the current block's
+ b_instr array. Resizes the b_instr as necessary.
+ Returns -1 on failure.
+*/
+
+static int
+compiler_next_instr(basicblock *b)
+{
+ assert(b != NULL);
+ if (b->b_instr == NULL) {
+ b->b_instr = (struct instr *)PyObject_Calloc(
+ DEFAULT_BLOCK_SIZE, sizeof(struct instr));
+ if (b->b_instr == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ b->b_ialloc = DEFAULT_BLOCK_SIZE;
+ }
+ else if (b->b_iused == b->b_ialloc) {
+ struct instr *tmp;
+ size_t oldsize, newsize;
+ oldsize = b->b_ialloc * sizeof(struct instr);
+ newsize = oldsize << 1;
+
+ if (oldsize > (SIZE_MAX >> 1)) {
+ PyErr_NoMemory();
+ return -1;
+ }
+
+ if (newsize == 0) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ b->b_ialloc <<= 1;
+ tmp = (struct instr *)PyObject_Realloc(
+ (void *)b->b_instr, newsize);
+ if (tmp == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ b->b_instr = tmp;
+ memset((char *)b->b_instr + oldsize, 0, newsize - oldsize);
+ }
+ return b->b_iused++;
+}
+
+/* Set the line number and column offset for the following instructions.
+
+ The line number is reset in the following cases:
+ - when entering a new scope
+ - on each statement
+ - on each expression and sub-expression
+ - before the "except" and "finally" clauses
+*/
+
+#define SET_LOC(c, x) \
+ (c)->u->u_lineno = (x)->lineno; \
+ (c)->u->u_col_offset = (x)->col_offset;
+
+/* Return the stack effect of opcode with argument oparg.
+
+ Some opcodes have different stack effect when jump to the target and
+ when not jump. The 'jump' parameter specifies the case:
+
+ * 0 -- when not jump
+ * 1 -- when jump
+ * -1 -- maximal
+ */
+/* XXX Make the stack effect of WITH_CLEANUP_START and
+ WITH_CLEANUP_FINISH deterministic. */
+static int
+stack_effect(int opcode, int oparg, int jump)
+{
+ switch (opcode) {
+ case NOP:
+ case EXTENDED_ARG:
+ return 0;
+
+ /* Stack manipulation */
+ case POP_TOP:
+ return -1;
+ case ROT_TWO:
+ case ROT_THREE:
+ case ROT_FOUR:
+ return 0;
+ case DUP_TOP:
+ return 1;
+ case DUP_TOP_TWO:
+ return 2;
+
+ /* Unary operators */
+ case UNARY_POSITIVE:
+ case UNARY_NEGATIVE:
+ case UNARY_NOT:
+ case UNARY_INVERT:
+ return 0;
+
+ case SET_ADD:
+ case LIST_APPEND:
+ return -1;
+ case MAP_ADD:
+ return -2;
+
+ /* Binary operators */
+ case BINARY_POWER:
+ case BINARY_MULTIPLY:
+ case BINARY_MATRIX_MULTIPLY:
+ case BINARY_MODULO:
+ case BINARY_ADD:
+ case BINARY_SUBTRACT:
+ case BINARY_SUBSCR:
+ case BINARY_FLOOR_DIVIDE:
+ case BINARY_TRUE_DIVIDE:
+ return -1;
+ case INPLACE_FLOOR_DIVIDE:
+ case INPLACE_TRUE_DIVIDE:
+ return -1;
+
+ case INPLACE_ADD:
+ case INPLACE_SUBTRACT:
+ case INPLACE_MULTIPLY:
+ case INPLACE_MATRIX_MULTIPLY:
+ case INPLACE_MODULO:
+ return -1;
+ case STORE_SUBSCR:
+ return -3;
+ case DELETE_SUBSCR:
+ return -2;
+
+ case BINARY_LSHIFT:
+ case BINARY_RSHIFT:
+ case BINARY_AND:
+ case BINARY_XOR:
+ case BINARY_OR:
+ return -1;
+ case INPLACE_POWER:
+ return -1;
+ case GET_ITER:
+ return 0;
+
+ case PRINT_EXPR:
+ return -1;
+ case LOAD_BUILD_CLASS:
+ return 1;
+ case INPLACE_LSHIFT:
+ case INPLACE_RSHIFT:
+ case INPLACE_AND:
+ case INPLACE_XOR:
+ case INPLACE_OR:
+ return -1;
+
+ case SETUP_WITH:
+ /* 1 in the normal flow.
+ * Restore the stack position and push 6 values before jumping to
+ * the handler if an exception be raised. */
+ return jump ? 6 : 1;
+ case RETURN_VALUE:
+ return -1;
+ case IMPORT_STAR:
+ return -1;
+ case SETUP_ANNOTATIONS:
+ return 0;
+ case YIELD_VALUE:
+ return 0;
+ case YIELD_FROM:
+ return -1;
+ case POP_BLOCK:
+ return 0;
+ case POP_EXCEPT:
+ return -3;
+
+ case STORE_NAME:
+ return -1;
+ case DELETE_NAME:
+ return 0;
+ case UNPACK_SEQUENCE:
+ return oparg-1;
+ case UNPACK_EX:
+ return (oparg&0xFF) + (oparg>>8);
+ case FOR_ITER:
+ /* -1 at end of iterator, 1 if continue iterating. */
+ return jump > 0 ? -1 : 1;
+
+ case STORE_ATTR:
+ return -2;
+ case DELETE_ATTR:
+ return -1;
+ case STORE_GLOBAL:
+ return -1;
+ case DELETE_GLOBAL:
+ return 0;
+ case LOAD_CONST:
+ return 1;
+ case LOAD_NAME:
+ return 1;
+ case BUILD_TUPLE:
+ case BUILD_LIST:
+ case BUILD_SET:
+ case BUILD_STRING:
+ return 1-oparg;
+ case BUILD_MAP:
+ return 1 - 2*oparg;
+ case BUILD_CONST_KEY_MAP:
+ return -oparg;
+ case LOAD_ATTR:
+ return 0;
+ case COMPARE_OP:
+ case IS_OP:
+ case CONTAINS_OP:
+ return -1;
+ case JUMP_IF_NOT_EXC_MATCH:
+ return -2;
+ case IMPORT_NAME:
+ return -1;
+ case IMPORT_FROM:
+ return 1;
+
+ /* Jumps */
+ case JUMP_FORWARD:
+ case JUMP_ABSOLUTE:
+ return 0;
+
+ case JUMP_IF_TRUE_OR_POP:
+ case JUMP_IF_FALSE_OR_POP:
+ return jump ? 0 : -1;
+
+ case POP_JUMP_IF_FALSE:
+ case POP_JUMP_IF_TRUE:
+ return -1;
+
+ case LOAD_GLOBAL:
+ return 1;
+
+ /* Exception handling */
+ case SETUP_FINALLY:
+ /* 0 in the normal flow.
+ * Restore the stack position and push 6 values before jumping to
+ * the handler if an exception be raised. */
+ return jump ? 6 : 0;
+ case RERAISE:
+ return -3;
+
+ case WITH_EXCEPT_START:
+ return 1;
+
+ case LOAD_FAST:
+ return 1;
+ case STORE_FAST:
+ return -1;
+ case DELETE_FAST:
+ return 0;
+
+ case RAISE_VARARGS:
+ return -oparg;
+
+ /* Functions and calls */
+ case CALL_FUNCTION:
+ return -oparg;
+ case CALL_METHOD:
+ return -oparg-1;
+ case CALL_FUNCTION_KW:
+ return -oparg-1;
+ case CALL_FUNCTION_EX:
+ return -1 - ((oparg & 0x01) != 0);
+ case MAKE_FUNCTION:
+ return -1 - ((oparg & 0x01) != 0) - ((oparg & 0x02) != 0) -
+ ((oparg & 0x04) != 0) - ((oparg & 0x08) != 0);
+ case BUILD_SLICE:
+ if (oparg == 3)
+ return -2;
+ else
+ return -1;
+
+ /* Closures */
+ case LOAD_CLOSURE:
+ return 1;
+ case LOAD_DEREF:
+ case LOAD_CLASSDEREF:
+ return 1;
+ case STORE_DEREF:
+ return -1;
+ case DELETE_DEREF:
+ return 0;
+
+ /* Iterators and generators */
+ case GET_AWAITABLE:
+ return 0;
+ case SETUP_ASYNC_WITH:
+ /* 0 in the normal flow.
+ * Restore the stack position to the position before the result
+ * of __aenter__ and push 6 values before jumping to the handler
+ * if an exception be raised. */
+ return jump ? -1 + 6 : 0;
+ case BEFORE_ASYNC_WITH:
+ return 1;
+ case GET_AITER:
+ return 0;
+ case GET_ANEXT:
+ return 1;
+ case GET_YIELD_FROM_ITER:
+ return 0;
+ case END_ASYNC_FOR:
+ return -7;
+ case FORMAT_VALUE:
+ /* If there's a fmt_spec on the stack, we go from 2->1,
+ else 1->1. */
+ return (oparg & FVS_MASK) == FVS_HAVE_SPEC ? -1 : 0;
+ case LOAD_METHOD:
+ return 1;
+ case LOAD_ASSERTION_ERROR:
+ return 1;
+ case LIST_TO_TUPLE:
+ return 0;
+ case LIST_EXTEND:
+ case SET_UPDATE:
+ case DICT_MERGE:
+ case DICT_UPDATE:
+ return -1;
+ default:
+ return PY_INVALID_STACK_EFFECT;
+ }
+ return PY_INVALID_STACK_EFFECT; /* not reachable */
+}
+
+int
+PyCompile_OpcodeStackEffectWithJump(int opcode, int oparg, int jump)
+{
+ return stack_effect(opcode, oparg, jump);
+}
+
+int
+PyCompile_OpcodeStackEffect(int opcode, int oparg)
+{
+ return stack_effect(opcode, oparg, -1);
+}
+
+/* Add an opcode with no argument.
+ Returns 0 on failure, 1 on success.
+*/
+
+static int
+compiler_addop(struct compiler *c, int opcode)
+{
+ basicblock *b;
+ struct instr *i;
+ int off;
+ assert(!HAS_ARG(opcode));
+ if (c->c_do_not_emit_bytecode) {
+ return 1;
+ }
+ off = compiler_next_instr(c->u->u_curblock);
+ if (off < 0)
+ return 0;
+ b = c->u->u_curblock;
+ i = &b->b_instr[off];
+ i->i_opcode = opcode;
+ i->i_oparg = 0;
+ if (opcode == RETURN_VALUE)
+ b->b_return = 1;
+ i->i_lineno = c->u->u_lineno;
+ return 1;
+}
+
+static Py_ssize_t
+compiler_add_o(PyObject *dict, PyObject *o)
+{
+ PyObject *v;
+ Py_ssize_t arg;
+
+ v = PyDict_GetItemWithError(dict, o);
+ if (!v) {
+ if (PyErr_Occurred()) {
+ return -1;
+ }
+ arg = PyDict_GET_SIZE(dict);
+ v = PyLong_FromSsize_t(arg);
+ if (!v) {
+ return -1;
+ }
+ if (PyDict_SetItem(dict, o, v) < 0) {
+ Py_DECREF(v);
+ return -1;
+ }
+ Py_DECREF(v);
+ }
+ else
+ arg = PyLong_AsLong(v);
+ return arg;
+}
+
+// Merge const *o* recursively and return constant key object.
+static PyObject*
+merge_consts_recursive(struct compiler *c, PyObject *o)
+{
+ // None and Ellipsis are singleton, and key is the singleton.
+ // No need to merge object and key.
+ if (o == Py_None || o == Py_Ellipsis) {
+ Py_INCREF(o);
+ return o;
+ }
+
+ PyObject *key = _PyCode_ConstantKey(o);
+ if (key == NULL) {
+ return NULL;
+ }
+
+ // t is borrowed reference
+ PyObject *t = PyDict_SetDefault(c->c_const_cache, key, key);
+ if (t != key) {
+ // o is registered in c_const_cache. Just use it.
+ Py_XINCREF(t);
+ Py_DECREF(key);
+ return t;
+ }
+
+ // We registered o in c_const_cache.
+ // When o is a tuple or frozenset, we want to merge its
+ // items too.
+ if (PyTuple_CheckExact(o)) {
+ Py_ssize_t len = PyTuple_GET_SIZE(o);
+ for (Py_ssize_t i = 0; i < len; i++) {
+ PyObject *item = PyTuple_GET_ITEM(o, i);
+ PyObject *u = merge_consts_recursive(c, item);
+ if (u == NULL) {
+ Py_DECREF(key);
+ return NULL;
+ }
+
+ // See _PyCode_ConstantKey()
+ PyObject *v; // borrowed
+ if (PyTuple_CheckExact(u)) {
+ v = PyTuple_GET_ITEM(u, 1);
+ }
+ else {
+ v = u;
+ }
+ if (v != item) {
+ Py_INCREF(v);
+ PyTuple_SET_ITEM(o, i, v);
+ Py_DECREF(item);
+ }
+
+ Py_DECREF(u);
+ }
+ }
+ else if (PyFrozenSet_CheckExact(o)) {
+ // *key* is tuple. And its first item is frozenset of
+ // constant keys.
+ // See _PyCode_ConstantKey() for detail.
+ assert(PyTuple_CheckExact(key));
+ assert(PyTuple_GET_SIZE(key) == 2);
+
+ Py_ssize_t len = PySet_GET_SIZE(o);
+ if (len == 0) { // empty frozenset should not be re-created.
+ return key;
+ }
+ PyObject *tuple = PyTuple_New(len);
+ if (tuple == NULL) {
+ Py_DECREF(key);
+ return NULL;
+ }
+ Py_ssize_t i = 0, pos = 0;
+ PyObject *item;
+ Py_hash_t hash;
+ while (_PySet_NextEntry(o, &pos, &item, &hash)) {
+ PyObject *k = merge_consts_recursive(c, item);
+ if (k == NULL) {
+ Py_DECREF(tuple);
+ Py_DECREF(key);
+ return NULL;
+ }
+ PyObject *u;
+ if (PyTuple_CheckExact(k)) {
+ u = PyTuple_GET_ITEM(k, 1);
+ Py_INCREF(u);
+ Py_DECREF(k);
+ }
+ else {
+ u = k;
+ }
+ PyTuple_SET_ITEM(tuple, i, u); // Steals reference of u.
+ i++;
+ }
+
+ // Instead of rewriting o, we create new frozenset and embed in the
+ // key tuple. Caller should get merged frozenset from the key tuple.
+ PyObject *new = PyFrozenSet_New(tuple);
+ Py_DECREF(tuple);
+ if (new == NULL) {
+ Py_DECREF(key);
+ return NULL;
+ }
+ assert(PyTuple_GET_ITEM(key, 1) == o);
+ Py_DECREF(o);
+ PyTuple_SET_ITEM(key, 1, new);
+ }
+
+ return key;
+}
+
+static Py_ssize_t
+compiler_add_const(struct compiler *c, PyObject *o)
+{
+ if (c->c_do_not_emit_bytecode) {
+ return 0;
+ }
+
+ PyObject *key = merge_consts_recursive(c, o);
+ if (key == NULL) {
+ return -1;
+ }
+
+ Py_ssize_t arg = compiler_add_o(c->u->u_consts, key);
+ Py_DECREF(key);
+ return arg;
+}
+
+static int
+compiler_addop_load_const(struct compiler *c, PyObject *o)
+{
+ if (c->c_do_not_emit_bytecode) {
+ return 1;
+ }
+
+ Py_ssize_t arg = compiler_add_const(c, o);
+ if (arg < 0)
+ return 0;
+ return compiler_addop_i(c, LOAD_CONST, arg);
+}
+
+static int
+compiler_addop_o(struct compiler *c, int opcode, PyObject *dict,
+ PyObject *o)
+{
+ if (c->c_do_not_emit_bytecode) {
+ return 1;
+ }
+
+ Py_ssize_t arg = compiler_add_o(dict, o);
+ if (arg < 0)
+ return 0;
+ return compiler_addop_i(c, opcode, arg);
+}
+
+static int
+compiler_addop_name(struct compiler *c, int opcode, PyObject *dict,
+ PyObject *o)
+{
+ Py_ssize_t arg;
+
+ if (c->c_do_not_emit_bytecode) {
+ return 1;
+ }
+
+ PyObject *mangled = _Py_Mangle(c->u->u_private, o);
+ if (!mangled)
+ return 0;
+ arg = compiler_add_o(dict, mangled);
+ Py_DECREF(mangled);
+ if (arg < 0)
+ return 0;
+ return compiler_addop_i(c, opcode, arg);
+}
+
+/* Add an opcode with an integer argument.
+ Returns 0 on failure, 1 on success.
+*/
+
+static int
+compiler_addop_i(struct compiler *c, int opcode, Py_ssize_t oparg)
+{
+ struct instr *i;
+ int off;
+
+ if (c->c_do_not_emit_bytecode) {
+ return 1;
+ }
+
+ /* oparg value is unsigned, but a signed C int is usually used to store
+ it in the C code (like Python/ceval.c).
+
+ Limit to 32-bit signed C int (rather than INT_MAX) for portability.
+
+ The argument of a concrete bytecode instruction is limited to 8-bit.
+ EXTENDED_ARG is used for 16, 24, and 32-bit arguments. */
+ assert(HAS_ARG(opcode));
+ assert(0 <= oparg && oparg <= 2147483647);
+
+ off = compiler_next_instr(c->u->u_curblock);
+ if (off < 0)
+ return 0;
+ i = &c->u->u_curblock->b_instr[off];
+ i->i_opcode = opcode;
+ i->i_oparg = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int);
+ i->i_lineno = c->u->u_lineno;
+ return 1;
+}
+
+static int
+compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute)
+{
+ struct instr *i;
+ int off;
+
+ if (c->c_do_not_emit_bytecode) {
+ return 1;
+ }
+
+ assert(HAS_ARG(opcode));
+ assert(b != NULL);
+ off = compiler_next_instr(c->u->u_curblock);
+ if (off < 0)
+ return 0;
+ i = &c->u->u_curblock->b_instr[off];
+ i->i_opcode = opcode;
+ i->i_target = b;
+ if (absolute)
+ i->i_jabs = 1;
+ else
+ i->i_jrel = 1;
+ i->i_lineno = c->u->u_lineno;
+ return 1;
+}
+
+/* NEXT_BLOCK() creates an implicit jump from the current block
+ to the new block.
+
+ The returns inside this macro make it impossible to decref objects
+ created in the local function. Local objects should use the arena.
+*/
+#define NEXT_BLOCK(C) { \
+ if (compiler_next_block((C)) == NULL) \
+ return 0; \
+}
+
+#define ADDOP(C, OP) { \
+ if (!compiler_addop((C), (OP))) \
+ return 0; \
+}
+
+#define ADDOP_IN_SCOPE(C, OP) { \
+ if (!compiler_addop((C), (OP))) { \
+ compiler_exit_scope(c); \
+ return 0; \
+ } \
+}
+
+#define ADDOP_LOAD_CONST(C, O) { \
+ if (!compiler_addop_load_const((C), (O))) \
+ return 0; \
+}
+
+/* Same as ADDOP_LOAD_CONST, but steals a reference. */
+#define ADDOP_LOAD_CONST_NEW(C, O) { \
+ PyObject *__new_const = (O); \
+ if (__new_const == NULL) { \
+ return 0; \
+ } \
+ if (!compiler_addop_load_const((C), __new_const)) { \
+ Py_DECREF(__new_const); \
+ return 0; \
+ } \
+ Py_DECREF(__new_const); \
+}
+
+#define ADDOP_O(C, OP, O, TYPE) { \
+ if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) \
+ return 0; \
+}
+
+/* Same as ADDOP_O, but steals a reference. */
+#define ADDOP_N(C, OP, O, TYPE) { \
+ if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) { \
+ Py_DECREF((O)); \
+ return 0; \
+ } \
+ Py_DECREF((O)); \
+}
+
+#define ADDOP_NAME(C, OP, O, TYPE) { \
+ if (!compiler_addop_name((C), (OP), (C)->u->u_ ## TYPE, (O))) \
+ return 0; \
+}
+
+#define ADDOP_I(C, OP, O) { \
+ if (!compiler_addop_i((C), (OP), (O))) \
+ return 0; \
+}
+
+#define ADDOP_JABS(C, OP, O) { \
+ if (!compiler_addop_j((C), (OP), (O), 1)) \
+ return 0; \
+}
+
+#define ADDOP_JREL(C, OP, O) { \
+ if (!compiler_addop_j((C), (OP), (O), 0)) \
+ return 0; \
+}
+
+
+#define ADDOP_COMPARE(C, CMP) { \
+ if (!compiler_addcompare((C), (cmpop_ty)(CMP))) \
+ return 0; \
+}
+
+/* VISIT and VISIT_SEQ takes an ASDL type as their second argument. They use
+ the ASDL name to synthesize the name of the C type and the visit function.
+*/
+
+#define VISIT(C, TYPE, V) {\
+ if (!compiler_visit_ ## TYPE((C), (V))) \
+ return 0; \
+}
+
+#define VISIT_IN_SCOPE(C, TYPE, V) {\
+ if (!compiler_visit_ ## TYPE((C), (V))) { \
+ compiler_exit_scope(c); \
+ return 0; \
+ } \
+}
+
+#define VISIT_SLICE(C, V, CTX) {\
+ if (!compiler_visit_slice((C), (V), (CTX))) \
+ return 0; \
+}
+
+#define VISIT_SEQ(C, TYPE, SEQ) { \
+ int _i; \
+ asdl_seq *seq = (SEQ); /* avoid variable capture */ \
+ for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \
+ TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \
+ if (!compiler_visit_ ## TYPE((C), elt)) \
+ return 0; \
+ } \
+}
+
+#define VISIT_SEQ_IN_SCOPE(C, TYPE, SEQ) { \
+ int _i; \
+ asdl_seq *seq = (SEQ); /* avoid variable capture */ \
+ for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \
+ TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \
+ if (!compiler_visit_ ## TYPE((C), elt)) { \
+ compiler_exit_scope(c); \
+ return 0; \
+ } \
+ } \
+}
+
+/* These macros allows to check only for errors and not emmit bytecode
+ * while visiting nodes.
+*/
+
+#define BEGIN_DO_NOT_EMIT_BYTECODE { \
+ c->c_do_not_emit_bytecode++;
+
+#define END_DO_NOT_EMIT_BYTECODE \
+ c->c_do_not_emit_bytecode--; \
+}
+
+/* Search if variable annotations are present statically in a block. */
+
+static int
+find_ann(asdl_seq *stmts)
+{
+ int i, j, res = 0;
+ stmt_ty st;
+
+ for (i = 0; i < asdl_seq_LEN(stmts); i++) {
+ st = (stmt_ty)asdl_seq_GET(stmts, i);
+ switch (st->kind) {
+ case AnnAssign_kind:
+ return 1;
+ case For_kind:
+ res = find_ann(st->v.For.body) ||
+ find_ann(st->v.For.orelse);
+ break;
+ case AsyncFor_kind:
+ res = find_ann(st->v.AsyncFor.body) ||
+ find_ann(st->v.AsyncFor.orelse);
+ break;
+ case While_kind:
+ res = find_ann(st->v.While.body) ||
+ find_ann(st->v.While.orelse);
+ break;
+ case If_kind:
+ res = find_ann(st->v.If.body) ||
+ find_ann(st->v.If.orelse);
+ break;
+ case With_kind:
+ res = find_ann(st->v.With.body);
+ break;
+ case AsyncWith_kind:
+ res = find_ann(st->v.AsyncWith.body);
+ break;
+ case Try_kind:
+ for (j = 0; j < asdl_seq_LEN(st->v.Try.handlers); j++) {
+ excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
+ st->v.Try.handlers, j);
+ if (find_ann(handler->v.ExceptHandler.body)) {
+ return 1;
+ }
+ }
+ res = find_ann(st->v.Try.body) ||
+ find_ann(st->v.Try.finalbody) ||
+ find_ann(st->v.Try.orelse);
+ break;
+ default:
+ res = 0;
+ }
+ if (res) {
+ break;
+ }
+ }
+ return res;
+}
+
+/*
+ * Frame block handling functions
+ */
+
+static int
+compiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b,
+ basicblock *exit, void *datum)
+{
+ struct fblockinfo *f;
+ if (c->u->u_nfblocks >= CO_MAXBLOCKS) {
+ return compiler_error(c, "too many statically nested blocks");
+ }
+ f = &c->u->u_fblock[c->u->u_nfblocks++];
+ f->fb_type = t;
+ f->fb_block = b;
+ f->fb_exit = exit;
+ f->fb_datum = datum;
+ return 1;
+}
+
+static void
+compiler_pop_fblock(struct compiler *c, enum fblocktype t, basicblock *b)
+{
+ struct compiler_unit *u = c->u;
+ assert(u->u_nfblocks > 0);
+ u->u_nfblocks--;
+ assert(u->u_fblock[u->u_nfblocks].fb_type == t);
+ assert(u->u_fblock[u->u_nfblocks].fb_block == b);
+}
+
+static int
+compiler_call_exit_with_nones(struct compiler *c) {
+ ADDOP_O(c, LOAD_CONST, Py_None, consts);
+ ADDOP(c, DUP_TOP);
+ ADDOP(c, DUP_TOP);
+ ADDOP_I(c, CALL_FUNCTION, 3);
+ return 1;
+}
+
+/* Unwind a frame block. If preserve_tos is true, the TOS before
+ * popping the blocks will be restored afterwards, unless another
+ * return, break or continue is found. In which case, the TOS will
+ * be popped.
+ */
+static int
+compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info,
+ int preserve_tos)
+{
+ switch (info->fb_type) {
+ case WHILE_LOOP:
+ case EXCEPTION_HANDLER:
+ return 1;
+
+ case FOR_LOOP:
+ /* Pop the iterator */
+ if (preserve_tos) {
+ ADDOP(c, ROT_TWO);
+ }
+ ADDOP(c, POP_TOP);
+ return 1;
+
+ case TRY_EXCEPT:
+ ADDOP(c, POP_BLOCK);
+ return 1;
+
+ case FINALLY_TRY:
+ ADDOP(c, POP_BLOCK);
+ if (preserve_tos) {
+ if (!compiler_push_fblock(c, POP_VALUE, NULL, NULL, NULL)) {
+ return 0;
+ }
+ }
+ /* Emit the finally block, restoring the line number when done */
+ int saved_lineno = c->u->u_lineno;
+ VISIT_SEQ(c, stmt, info->fb_datum);
+ c->u->u_lineno = saved_lineno;
+ if (preserve_tos) {
+ compiler_pop_fblock(c, POP_VALUE, NULL);
+ }
+ return 1;
+
+ case FINALLY_END:
+ if (preserve_tos) {
+ ADDOP(c, ROT_FOUR);
+ }
+ ADDOP(c, POP_TOP);
+ ADDOP(c, POP_TOP);
+ ADDOP(c, POP_TOP);
+ if (preserve_tos) {
+ ADDOP(c, ROT_FOUR);
+ }
+ ADDOP(c, POP_EXCEPT);
+ return 1;
+
+ case WITH:
+ case ASYNC_WITH:
+ ADDOP(c, POP_BLOCK);
+ if (preserve_tos) {
+ ADDOP(c, ROT_TWO);
+ }
+ if(!compiler_call_exit_with_nones(c)) {
+ return 0;
+ }
+ if (info->fb_type == ASYNC_WITH) {
+ ADDOP(c, GET_AWAITABLE);
+ ADDOP_LOAD_CONST(c, Py_None);
+ ADDOP(c, YIELD_FROM);
+ }
+ ADDOP(c, POP_TOP);
+ return 1;
+
+ case HANDLER_CLEANUP:
+ if (info->fb_datum) {
+ ADDOP(c, POP_BLOCK);
+ }
+ if (preserve_tos) {
+ ADDOP(c, ROT_FOUR);
+ }
+ ADDOP(c, POP_EXCEPT);
+ if (info->fb_datum) {
+ ADDOP_LOAD_CONST(c, Py_None);
+ compiler_nameop(c, info->fb_datum, Store);
+ compiler_nameop(c, info->fb_datum, Del);
+ }
+ return 1;
+
+ case POP_VALUE:
+ if (preserve_tos) {
+ ADDOP(c, ROT_TWO);
+ }
+ ADDOP(c, POP_TOP);
+ return 1;
+ }
+ Py_UNREACHABLE();
+}
+
+/** Unwind block stack. If loop is not NULL, then stop when the first loop is encountered. */
+static int
+compiler_unwind_fblock_stack(struct compiler *c, int preserve_tos, struct fblockinfo **loop) {
+ if (c->u->u_nfblocks == 0) {
+ return 1;
+ }
+ struct fblockinfo *top = &c->u->u_fblock[c->u->u_nfblocks-1];
+ if (loop != NULL && (top->fb_type == WHILE_LOOP || top->fb_type == FOR_LOOP)) {
+ *loop = top;
+ return 1;
+ }
+ struct fblockinfo copy = *top;
+ c->u->u_nfblocks--;
+ if (!compiler_unwind_fblock(c, &copy, preserve_tos)) {
+ return 0;
+ }
+ if (!compiler_unwind_fblock_stack(c, preserve_tos, loop)) {
+ return 0;
+ }
+ c->u->u_fblock[c->u->u_nfblocks] = copy;
+ c->u->u_nfblocks++;
+ return 1;
+}
+
+/* Compile a sequence of statements, checking for a docstring
+ and for annotations. */
+
+static int
+compiler_body(struct compiler *c, asdl_seq *stmts)
+{
+ int i = 0;
+ stmt_ty st;
+ PyObject *docstring;
+
+ /* Set current line number to the line number of first statement.
+ This way line number for SETUP_ANNOTATIONS will always
+ coincide with the line number of first "real" statement in module.
+ If body is empty, then lineno will be set later in assemble. */
+ if (c->u->u_scope_type == COMPILER_SCOPE_MODULE && asdl_seq_LEN(stmts)) {
+ st = (stmt_ty)asdl_seq_GET(stmts, 0);
+ SET_LOC(c, st);
+ }
+ /* Every annotated class and module should have __annotations__. */
+ if (find_ann(stmts)) {
+ ADDOP(c, SETUP_ANNOTATIONS);
+ }
+ if (!asdl_seq_LEN(stmts))
+ return 1;
+ /* if not -OO mode, set docstring */
+ if (c->c_optimize < 2) {
+ docstring = _PyAST_GetDocString(stmts);
+ if (docstring) {
+ i = 1;
+ st = (stmt_ty)asdl_seq_GET(stmts, 0);
+ assert(st->kind == Expr_kind);
+ VISIT(c, expr, st->v.Expr.value);
+ if (!compiler_nameop(c, __doc__, Store))
+ return 0;
+ }
+ }
+ for (; i < asdl_seq_LEN(stmts); i++)
+ VISIT(c, stmt, (stmt_ty)asdl_seq_GET(stmts, i));
+ return 1;
+}
+
+static PyCodeObject *
+compiler_mod(struct compiler *c, mod_ty mod)
+{
+ PyCodeObject *co;
+ int addNone = 1;
+ static PyObject *module;
+ if (!module) {
+ module = PyUnicode_InternFromString("<module>");
+ if (!module)
+ return NULL;
+ }
+ /* Use 0 for firstlineno initially, will fixup in assemble(). */
+ if (!compiler_enter_scope(c, module, COMPILER_SCOPE_MODULE, mod, 0))
+ return NULL;
+ switch (mod->kind) {
+ case Module_kind:
+ if (!compiler_body(c, mod->v.Module.body)) {
+ compiler_exit_scope(c);
+ return 0;
+ }
+ break;
+ case Interactive_kind:
+ if (find_ann(mod->v.Interactive.body)) {
+ ADDOP(c, SETUP_ANNOTATIONS);
+ }
+ c->c_interactive = 1;
+ VISIT_SEQ_IN_SCOPE(c, stmt,
+ mod->v.Interactive.body);
+ break;
+ case Expression_kind:
+ VISIT_IN_SCOPE(c, expr, mod->v.Expression.body);
+ addNone = 0;
+ break;
+ default:
+ PyErr_Format(PyExc_SystemError,
+ "module kind %d should not be possible",
+ mod->kind);
+ return 0;
+ }
+ co = assemble(c, addNone);
+ compiler_exit_scope(c);
+ return co;
+}
+
+/* The test for LOCAL must come before the test for FREE in order to
+ handle classes where name is both local and free. The local var is
+ a method and the free var is a free var referenced within a method.
+*/
+
+static int
+get_ref_type(struct compiler *c, PyObject *name)
+{
+ int scope;
+ if (c->u->u_scope_type == COMPILER_SCOPE_CLASS &&
+ _PyUnicode_EqualToASCIIString(name, "__class__"))
+ return CELL;
+ scope = PyST_GetScope(c->u->u_ste, name);
+ if (scope == 0) {
+ _Py_FatalErrorFormat(__func__,
+ "unknown scope for %.100s in %.100s(%s)\n"
+ "symbols: %s\nlocals: %s\nglobals: %s",
+ PyUnicode_AsUTF8(name),
+ PyUnicode_AsUTF8(c->u->u_name),
+ PyUnicode_AsUTF8(PyObject_Repr(c->u->u_ste->ste_id)),
+ PyUnicode_AsUTF8(PyObject_Repr(c->u->u_ste->ste_symbols)),
+ PyUnicode_AsUTF8(PyObject_Repr(c->u->u_varnames)),
+ PyUnicode_AsUTF8(PyObject_Repr(c->u->u_names)));
+ }
+
+ return scope;
+}
+
+static int
+compiler_lookup_arg(PyObject *dict, PyObject *name)
+{
+ PyObject *v;
+ v = PyDict_GetItem(dict, name);
+ if (v == NULL)
+ return -1;
+ return PyLong_AS_LONG(v);
+}
+
+static int
+compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, PyObject *qualname)
+{
+ Py_ssize_t i, free = PyCode_GetNumFree(co);
+ if (qualname == NULL)
+ qualname = co->co_name;
+
+ if (free) {
+ for (i = 0; i < free; ++i) {
+ /* Bypass com_addop_varname because it will generate
+ LOAD_DEREF but LOAD_CLOSURE is needed.
+ */
+ PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i);
+ int arg, reftype;
+
+ /* Special case: If a class contains a method with a
+ free variable that has the same name as a method,
+ the name will be considered free *and* local in the
+ class. It should be handled by the closure, as
+ well as by the normal name lookup logic.
+ */
+ reftype = get_ref_type(c, name);
+ if (reftype == CELL)
+ arg = compiler_lookup_arg(c->u->u_cellvars, name);
+ else /* (reftype == FREE) */
+ arg = compiler_lookup_arg(c->u->u_freevars, name);
+ if (arg == -1) {
+ _Py_FatalErrorFormat(__func__,
+ "lookup %s in %s %d %d\n"
+ "freevars of %s: %s\n",
+ PyUnicode_AsUTF8(PyObject_Repr(name)),
+ PyUnicode_AsUTF8(c->u->u_name),
+ reftype, arg,
+ PyUnicode_AsUTF8(co->co_name),
+ PyUnicode_AsUTF8(PyObject_Repr(co->co_freevars)));
+ }
+ ADDOP_I(c, LOAD_CLOSURE, arg);
+ }
+ flags |= 0x08;
+ ADDOP_I(c, BUILD_TUPLE, free);
+ }
+ ADDOP_LOAD_CONST(c, (PyObject*)co);
+ ADDOP_LOAD_CONST(c, qualname);
+ ADDOP_I(c, MAKE_FUNCTION, flags);
+ return 1;
+}
+
+static int
+compiler_decorators(struct compiler *c, asdl_seq* decos)
+{
+ int i;
+
+ if (!decos)
+ return 1;
+
+ for (i = 0; i < asdl_seq_LEN(decos); i++) {
+ VISIT(c, expr, (expr_ty)asdl_seq_GET(decos, i));
+ }
+ return 1;
+}
+
+static int
+compiler_visit_kwonlydefaults(struct compiler *c, asdl_seq *kwonlyargs,
+ asdl_seq *kw_defaults)
+{
+ /* Push a dict of keyword-only default values.
+
+ Return 0 on error, -1 if no dict pushed, 1 if a dict is pushed.
+ */
+ int i;
+ PyObject *keys = NULL;
+
+ for (i = 0; i < asdl_seq_LEN(kwonlyargs); i++) {
+ arg_ty arg = asdl_seq_GET(kwonlyargs, i);
+ expr_ty default_ = asdl_seq_GET(kw_defaults, i);
+ if (default_) {
+ PyObject *mangled = _Py_Mangle(c->u->u_private, arg->arg);
+ if (!mangled) {
+ goto error;
+ }
+ if (keys == NULL) {
+ keys = PyList_New(1);
+ if (keys == NULL) {
+ Py_DECREF(mangled);
+ return 0;
+ }
+ PyList_SET_ITEM(keys, 0, mangled);
+ }
+ else {
+ int res = PyList_Append(keys, mangled);
+ Py_DECREF(mangled);
+ if (res == -1) {
+ goto error;
+ }
+ }
+ if (!compiler_visit_expr(c, default_)) {
+ goto error;
+ }
+ }
+ }
+ if (keys != NULL) {
+ Py_ssize_t default_count = PyList_GET_SIZE(keys);
+ PyObject *keys_tuple = PyList_AsTuple(keys);
+ Py_DECREF(keys);
+ ADDOP_LOAD_CONST_NEW(c, keys_tuple);
+ ADDOP_I(c, BUILD_CONST_KEY_MAP, default_count);
+ assert(default_count > 0);
+ return 1;
+ }
+ else {
+ return -1;
+ }
+
+error:
+ Py_XDECREF(keys);
+ return 0;
+}
+
+static int
+compiler_visit_annexpr(struct compiler *c, expr_ty annotation)
+{
+ ADDOP_LOAD_CONST_NEW(c, _PyAST_ExprAsUnicode(annotation));
+ return 1;
+}
+
+static int
+compiler_visit_argannotation(struct compiler *c, identifier id,
+ expr_ty annotation, PyObject *names)
+{
+ if (annotation) {
+ PyObject *mangled;
+ if (c->c_future->ff_features & CO_FUTURE_ANNOTATIONS) {
+ VISIT(c, annexpr, annotation)
+ }
+ else {
+ VISIT(c, expr, annotation);
+ }
+ mangled = _Py_Mangle(c->u->u_private, id);
+ if (!mangled)
+ return 0;
+ if (PyList_Append(names, mangled) < 0) {
+ Py_DECREF(mangled);
+ return 0;
+ }
+ Py_DECREF(mangled);
+ }
+ return 1;
+}
+
+static int
+compiler_visit_argannotations(struct compiler *c, asdl_seq* args,
+ PyObject *names)
+{
+ int i;
+ for (i = 0; i < asdl_seq_LEN(args); i++) {
+ arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
+ if (!compiler_visit_argannotation(
+ c,
+ arg->arg,
+ arg->annotation,
+ names))
+ return 0;
+ }
+ return 1;
+}
+
+static int
+compiler_visit_annotations(struct compiler *c, arguments_ty args,
+ expr_ty returns)
+{
+ /* Push arg annotation dict.
+ The expressions are evaluated out-of-order wrt the source code.
+
+ Return 0 on error, -1 if no dict pushed, 1 if a dict is pushed.
+ */
+ static identifier return_str;
+ PyObject *names;
+ Py_ssize_t len;
+ names = PyList_New(0);
+ if (!names)
+ return 0;
+
+ if (!compiler_visit_argannotations(c, args->args, names))
+ goto error;
+ if (!compiler_visit_argannotations(c, args->posonlyargs, names))
+ goto error;
+ if (args->vararg && args->vararg->annotation &&
+ !compiler_visit_argannotation(c, args->vararg->arg,
+ args->vararg->annotation, names))
+ goto error;
+ if (!compiler_visit_argannotations(c, args->kwonlyargs, names))
+ goto error;
+ if (args->kwarg && args->kwarg->annotation &&
+ !compiler_visit_argannotation(c, args->kwarg->arg,
+ args->kwarg->annotation, names))
+ goto error;
+
+ if (!return_str) {
+ return_str = PyUnicode_InternFromString("return");
+ if (!return_str)
+ goto error;
+ }
+ if (!compiler_visit_argannotation(c, return_str, returns, names)) {
+ goto error;
+ }
+
+ len = PyList_GET_SIZE(names);
+ if (len) {
+ PyObject *keytuple = PyList_AsTuple(names);
+ Py_DECREF(names);
+ ADDOP_LOAD_CONST_NEW(c, keytuple);
+ ADDOP_I(c, BUILD_CONST_KEY_MAP, len);
+ return 1;
+ }
+ else {
+ Py_DECREF(names);
+ return -1;
+ }
+
+error:
+ Py_DECREF(names);
+ return 0;
+}
+
+static int
+compiler_visit_defaults(struct compiler *c, arguments_ty args)
+{
+ VISIT_SEQ(c, expr, args->defaults);
+ ADDOP_I(c, BUILD_TUPLE, asdl_seq_LEN(args->defaults));
+ return 1;
+}
+
+static Py_ssize_t
+compiler_default_arguments(struct compiler *c, arguments_ty args)
+{
+ Py_ssize_t funcflags = 0;
+ if (args->defaults && asdl_seq_LEN(args->defaults) > 0) {
+ if (!compiler_visit_defaults(c, args))
+ return -1;
+ funcflags |= 0x01;
+ }
+ if (args->kwonlyargs) {
+ int res = compiler_visit_kwonlydefaults(c, args->kwonlyargs,
+ args->kw_defaults);
+ if (res == 0) {
+ return -1;
+ }
+ else if (res > 0) {
+ funcflags |= 0x02;
+ }
+ }
+ return funcflags;
+}
+
+static int
+forbidden_name(struct compiler *c, identifier name, expr_context_ty ctx)
+{
+
+ if (ctx == Store && _PyUnicode_EqualToASCIIString(name, "__debug__")) {
+ compiler_error(c, "cannot assign to __debug__");
+ return 1;
+ }
+ return 0;
+}
+
+static int
+compiler_check_debug_one_arg(struct compiler *c, arg_ty arg)
+{
+ if (arg != NULL) {
+ if (forbidden_name(c, arg->arg, Store))
+ return 0;
+ }
+ return 1;
+}
+
+static int
+compiler_check_debug_args_seq(struct compiler *c, asdl_seq *args)
+{
+ if (args != NULL) {
+ for (Py_ssize_t i = 0, n = asdl_seq_LEN(args); i < n; i++) {
+ if (!compiler_check_debug_one_arg(c, asdl_seq_GET(args, i)))
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int
+compiler_check_debug_args(struct compiler *c, arguments_ty args)
+{
+ if (!compiler_check_debug_args_seq(c, args->posonlyargs))
+ return 0;
+ if (!compiler_check_debug_args_seq(c, args->args))
+ return 0;
+ if (!compiler_check_debug_one_arg(c, args->vararg))
+ return 0;
+ if (!compiler_check_debug_args_seq(c, args->kwonlyargs))
+ return 0;
+ if (!compiler_check_debug_one_arg(c, args->kwarg))
+ return 0;
+ return 1;
+}
+
+static int
+compiler_function(struct compiler *c, stmt_ty s, int is_async)
+{
+ PyCodeObject *co;
+ PyObject *qualname, *docstring = NULL;
+ arguments_ty args;
+ expr_ty returns;
+ identifier name;
+ asdl_seq* decos;
+ asdl_seq *body;
+ Py_ssize_t i, funcflags;
+ int annotations;
+ int scope_type;
+ int firstlineno;
+
+ if (is_async) {
+ assert(s->kind == AsyncFunctionDef_kind);
+
+ args = s->v.AsyncFunctionDef.args;
+ returns = s->v.AsyncFunctionDef.returns;
+ decos = s->v.AsyncFunctionDef.decorator_list;
+ name = s->v.AsyncFunctionDef.name;
+ body = s->v.AsyncFunctionDef.body;
+
+ scope_type = COMPILER_SCOPE_ASYNC_FUNCTION;
+ } else {
+ assert(s->kind == FunctionDef_kind);
+
+ args = s->v.FunctionDef.args;
+ returns = s->v.FunctionDef.returns;
+ decos = s->v.FunctionDef.decorator_list;
+ name = s->v.FunctionDef.name;
+ body = s->v.FunctionDef.body;
+
+ scope_type = COMPILER_SCOPE_FUNCTION;
+ }
+
+ if (!compiler_check_debug_args(c, args))
+ return 0;
+
+ if (!compiler_decorators(c, decos))
+ return 0;
+
+ firstlineno = s->lineno;
+ if (asdl_seq_LEN(decos)) {
+ firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno;
+ }
+
+ funcflags = compiler_default_arguments(c, args);
+ if (funcflags == -1) {
+ return 0;
+ }
+
+ annotations = compiler_visit_annotations(c, args, returns);
+ if (annotations == 0) {
+ return 0;
+ }
+ else if (annotations > 0) {
+ funcflags |= 0x04;
+ }
+
+ if (!compiler_enter_scope(c, name, scope_type, (void *)s, firstlineno)) {
+ return 0;
+ }
+
+ /* if not -OO mode, add docstring */
+ if (c->c_optimize < 2) {
+ docstring = _PyAST_GetDocString(body);
+ }
+ if (compiler_add_const(c, docstring ? docstring : Py_None) < 0) {
+ compiler_exit_scope(c);
+ return 0;
+ }
+
+ c->u->u_argcount = asdl_seq_LEN(args->args);
+ c->u->u_posonlyargcount = asdl_seq_LEN(args->posonlyargs);
+ c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs);
+ VISIT_SEQ_IN_SCOPE(c, stmt, body);
+ co = assemble(c, 1);
+ qualname = c->u->u_qualname;
+ Py_INCREF(qualname);
+ compiler_exit_scope(c);
+ if (co == NULL) {
+ Py_XDECREF(qualname);
+ Py_XDECREF(co);
+ return 0;
+ }
+
+ compiler_make_closure(c, co, funcflags, qualname);
+ Py_DECREF(qualname);
+ Py_DECREF(co);
+
+ /* decorators */
+ for (i = 0; i < asdl_seq_LEN(decos); i++) {
+ ADDOP_I(c, CALL_FUNCTION, 1);
+ }
+
+ return compiler_nameop(c, name, Store);
+}
+
+static int
+compiler_class(struct compiler *c, stmt_ty s)
+{
+ PyCodeObject *co;
+ PyObject *str;
+ int i, firstlineno;
+ asdl_seq* decos = s->v.ClassDef.decorator_list;
+
+ if (!compiler_decorators(c, decos))
+ return 0;
+
+ firstlineno = s->lineno;
+ if (asdl_seq_LEN(decos)) {
+ firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno;
+ }
+
+ /* ultimately generate code for:
+ <name> = __build_class__(<func>, <name>, *<bases>, **<keywords>)
+ where:
+ <func> is a function/closure created from the class body;
+ it has a single argument (__locals__) where the dict
+ (or MutableSequence) representing the locals is passed
+ <name> is the class name
+ <bases> is the positional arguments and *varargs argument
+ <keywords> is the keyword arguments and **kwds argument
+ This borrows from compiler_call.
+ */
+
+ /* 1. compile the class body into a code object */
+ if (!compiler_enter_scope(c, s->v.ClassDef.name,
+ COMPILER_SCOPE_CLASS, (void *)s, firstlineno))
+ return 0;
+ /* this block represents what we do in the new scope */
+ {
+ /* use the class name for name mangling */
+ Py_INCREF(s->v.ClassDef.name);
+ Py_XSETREF(c->u->u_private, s->v.ClassDef.name);
+ /* load (global) __name__ ... */
+ str = PyUnicode_InternFromString("__name__");
+ if (!str || !compiler_nameop(c, str, Load)) {
+ Py_XDECREF(str);
+ compiler_exit_scope(c);
+ return 0;
+ }
+ Py_DECREF(str);
+ /* ... and store it as __module__ */
+ str = PyUnicode_InternFromString("__module__");
+ if (!str || !compiler_nameop(c, str, Store)) {
+ Py_XDECREF(str);
+ compiler_exit_scope(c);
+ return 0;
+ }
+ Py_DECREF(str);
+ assert(c->u->u_qualname);
+ ADDOP_LOAD_CONST(c, c->u->u_qualname);
+ str = PyUnicode_InternFromString("__qualname__");
+ if (!str || !compiler_nameop(c, str, Store)) {
+ Py_XDECREF(str);
+ compiler_exit_scope(c);
+ return 0;
+ }
+ Py_DECREF(str);
+ /* compile the body proper */
+ if (!compiler_body(c, s->v.ClassDef.body)) {
+ compiler_exit_scope(c);
+ return 0;
+ }
+ /* Return __classcell__ if it is referenced, otherwise return None */
+ if (c->u->u_ste->ste_needs_class_closure) {
+ /* Store __classcell__ into class namespace & return it */
+ str = PyUnicode_InternFromString("__class__");
+ if (str == NULL) {
+ compiler_exit_scope(c);
+ return 0;
+ }
+ i = compiler_lookup_arg(c->u->u_cellvars, str);
+ Py_DECREF(str);
+ if (i < 0) {
+ compiler_exit_scope(c);
+ return 0;
+ }
+ assert(i == 0);
+
+ ADDOP_I(c, LOAD_CLOSURE, i);
+ ADDOP(c, DUP_TOP);
+ str = PyUnicode_InternFromString("__classcell__");
+ if (!str || !compiler_nameop(c, str, Store)) {
+ Py_XDECREF(str);
+ compiler_exit_scope(c);
+ return 0;
+ }
+ Py_DECREF(str);
+ }
+ else {
+ /* No methods referenced __class__, so just return None */
+ assert(PyDict_GET_SIZE(c->u->u_cellvars) == 0);
+ ADDOP_LOAD_CONST(c, Py_None);
+ }
+ ADDOP_IN_SCOPE(c, RETURN_VALUE);
+ /* create the code object */
+ co = assemble(c, 1);
+ }
+ /* leave the new scope */
+ compiler_exit_scope(c);
+ if (co == NULL)
+ return 0;
+
+ /* 2. load the 'build_class' function */
+ ADDOP(c, LOAD_BUILD_CLASS);
+
+ /* 3. load a function (or closure) made from the code object */
+ compiler_make_closure(c, co, 0, NULL);
+ Py_DECREF(co);
+
+ /* 4. load class name */
+ ADDOP_LOAD_CONST(c, s->v.ClassDef.name);
+
+ /* 5. generate the rest of the code for the call */
+ if (!compiler_call_helper(c, 2,
+ s->v.ClassDef.bases,
+ s->v.ClassDef.keywords))
+ return 0;
+
+ /* 6. apply decorators */
+ for (i = 0; i < asdl_seq_LEN(decos); i++) {
+ ADDOP_I(c, CALL_FUNCTION, 1);
+ }
+
+ /* 7. store into <name> */
+ if (!compiler_nameop(c, s->v.ClassDef.name, Store))
+ return 0;
+ return 1;
+}
+
+/* Return 0 if the expression is a constant value except named singletons.
+ Return 1 otherwise. */
+static int
+check_is_arg(expr_ty e)
+{
+ if (e->kind != Constant_kind) {
+ return 1;
+ }
+ PyObject *value = e->v.Constant.value;
+ return (value == Py_None
+ || value == Py_False
+ || value == Py_True
+ || value == Py_Ellipsis);
+}
+
+/* Check operands of identity chacks ("is" and "is not").
+ Emit a warning if any operand is a constant except named singletons.
+ Return 0 on error.
+ */
+static int
+check_compare(struct compiler *c, expr_ty e)
+{
+ Py_ssize_t i, n;
+ int left = check_is_arg(e->v.Compare.left);
+ n = asdl_seq_LEN(e->v.Compare.ops);
+ for (i = 0; i < n; i++) {
+ cmpop_ty op = (cmpop_ty)asdl_seq_GET(e->v.Compare.ops, i);
+ int right = check_is_arg((expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
+ if (op == Is || op == IsNot) {
+ if (!right || !left) {
+ const char *msg = (op == Is)
+ ? "\"is\" with a literal. Did you mean \"==\"?"
+ : "\"is not\" with a literal. Did you mean \"!=\"?";
+ return compiler_warn(c, msg);
+ }
+ }
+ left = right;
+ }
+ return 1;
+}
+
+static int compiler_addcompare(struct compiler *c, cmpop_ty op)
+{
+ int cmp;
+ switch (op) {
+ case Eq:
+ cmp = Py_EQ;
+ break;
+ case NotEq:
+ cmp = Py_NE;
+ break;
+ case Lt:
+ cmp = Py_LT;
+ break;
+ case LtE:
+ cmp = Py_LE;
+ break;
+ case Gt:
+ cmp = Py_GT;
+ break;
+ case GtE:
+ cmp = Py_GE;
+ break;
+ case Is:
+ ADDOP_I(c, IS_OP, 0);
+ return 1;
+ case IsNot:
+ ADDOP_I(c, IS_OP, 1);
+ return 1;
+ case In:
+ ADDOP_I(c, CONTAINS_OP, 0);
+ return 1;
+ case NotIn:
+ ADDOP_I(c, CONTAINS_OP, 1);
+ return 1;
+ default:
+ Py_UNREACHABLE();
+ }
+ ADDOP_I(c, COMPARE_OP, cmp);
+ return 1;
+}
+
+
+
+static int
+compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond)
+{
+ switch (e->kind) {
+ case UnaryOp_kind:
+ if (e->v.UnaryOp.op == Not)
+ return compiler_jump_if(c, e->v.UnaryOp.operand, next, !cond);
+ /* fallback to general implementation */
+ break;
+ case BoolOp_kind: {
+ asdl_seq *s = e->v.BoolOp.values;
+ Py_ssize_t i, n = asdl_seq_LEN(s) - 1;
+ assert(n >= 0);
+ int cond2 = e->v.BoolOp.op == Or;
+ basicblock *next2 = next;
+ if (!cond2 != !cond) {
+ next2 = compiler_new_block(c);
+ if (next2 == NULL)
+ return 0;
+ }
+ for (i = 0; i < n; ++i) {
+ if (!compiler_jump_if(c, (expr_ty)asdl_seq_GET(s, i), next2, cond2))
+ return 0;
+ }
+ if (!compiler_jump_if(c, (expr_ty)asdl_seq_GET(s, n), next, cond))
+ return 0;
+ if (next2 != next)
+ compiler_use_next_block(c, next2);
+ return 1;
+ }
+ case IfExp_kind: {
+ basicblock *end, *next2;
+ end = compiler_new_block(c);
+ if (end == NULL)
+ return 0;
+ next2 = compiler_new_block(c);
+ if (next2 == NULL)
+ return 0;
+ if (!compiler_jump_if(c, e->v.IfExp.test, next2, 0))
+ return 0;
+ if (!compiler_jump_if(c, e->v.IfExp.body, next, cond))
+ return 0;
+ ADDOP_JREL(c, JUMP_FORWARD, end);
+ compiler_use_next_block(c, next2);
+ if (!compiler_jump_if(c, e->v.IfExp.orelse, next, cond))
+ return 0;
+ compiler_use_next_block(c, end);
+ return 1;
+ }
+ case Compare_kind: {
+ Py_ssize_t i, n = asdl_seq_LEN(e->v.Compare.ops) - 1;
+ if (n > 0) {
+ if (!check_compare(c, e)) {
+ return 0;
+ }
+ basicblock *cleanup = compiler_new_block(c);
+ if (cleanup == NULL)
+ return 0;
+ VISIT(c, expr, e->v.Compare.left);
+ for (i = 0; i < n; i++) {
+ VISIT(c, expr,
+ (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
+ ADDOP(c, DUP_TOP);
+ ADDOP(c, ROT_THREE);
+ ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, i));
+ ADDOP_JABS(c, POP_JUMP_IF_FALSE, cleanup);
+ NEXT_BLOCK(c);
+ }
+ VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n));
+ ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, n));
+ ADDOP_JABS(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
+ basicblock *end = compiler_new_block(c);
+ if (end == NULL)
+ return 0;
+ ADDOP_JREL(c, JUMP_FORWARD, end);
+ compiler_use_next_block(c, cleanup);
+ ADDOP(c, POP_TOP);
+ if (!cond) {
+ ADDOP_JREL(c, JUMP_FORWARD, next);
+ }
+ compiler_use_next_block(c, end);
+ return 1;
+ }
+ /* fallback to general implementation */
+ break;
+ }
+ default:
+ /* fallback to general implementation */
+ break;
+ }
+
+ /* general implementation */
+ VISIT(c, expr, e);
+ ADDOP_JABS(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
+ return 1;
+}
+
+static int
+compiler_ifexp(struct compiler *c, expr_ty e)
+{
+ basicblock *end, *next;
+
+ assert(e->kind == IfExp_kind);
+ end = compiler_new_block(c);
+ if (end == NULL)
+ return 0;
+ next = compiler_new_block(c);
+ if (next == NULL)
+ return 0;
+ if (!compiler_jump_if(c, e->v.IfExp.test, next, 0))
+ return 0;
+ VISIT(c, expr, e->v.IfExp.body);
+ ADDOP_JREL(c, JUMP_FORWARD, end);
+ compiler_use_next_block(c, next);
+ VISIT(c, expr, e->v.IfExp.orelse);
+ compiler_use_next_block(c, end);
+ return 1;
+}
+
+static int
+compiler_lambda(struct compiler *c, expr_ty e)
+{
+ PyCodeObject *co;
+ PyObject *qualname;
+ static identifier name;
+ Py_ssize_t funcflags;
+ arguments_ty args = e->v.Lambda.args;
+ assert(e->kind == Lambda_kind);
+
+ if (!compiler_check_debug_args(c, args))
+ return 0;
+
+ if (!name) {
+ name = PyUnicode_InternFromString("<lambda>");
+ if (!name)
+ return 0;
+ }
+
+ funcflags = compiler_default_arguments(c, args);
+ if (funcflags == -1) {
+ return 0;
+ }
+
+ if (!compiler_enter_scope(c, name, COMPILER_SCOPE_LAMBDA,
+ (void *)e, e->lineno))
+ return 0;
+
+ /* Make None the first constant, so the lambda can't have a
+ docstring. */
+ if (compiler_add_const(c, Py_None) < 0)
+ return 0;
+
+ c->u->u_argcount = asdl_seq_LEN(args->args);
+ c->u->u_posonlyargcount = asdl_seq_LEN(args->posonlyargs);
+ c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs);
+ VISIT_IN_SCOPE(c, expr, e->v.Lambda.body);
+ if (c->u->u_ste->ste_generator) {
+ co = assemble(c, 0);
+ }
+ else {
+ ADDOP_IN_SCOPE(c, RETURN_VALUE);
+ co = assemble(c, 1);
+ }
+ qualname = c->u->u_qualname;
+ Py_INCREF(qualname);
+ compiler_exit_scope(c);
+ if (co == NULL)
+ return 0;
+
+ compiler_make_closure(c, co, funcflags, qualname);
+ Py_DECREF(qualname);
+ Py_DECREF(co);
+
+ return 1;
+}
+
+static int
+compiler_if(struct compiler *c, stmt_ty s)
+{
+ basicblock *end, *next;
+ int constant;
+ assert(s->kind == If_kind);
+ end = compiler_new_block(c);
+ if (end == NULL)
+ return 0;
+
+ constant = expr_constant(s->v.If.test);
+ /* constant = 0: "if 0"
+ * constant = 1: "if 1", "if 2", ...
+ * constant = -1: rest */
+ if (constant == 0) {
+ BEGIN_DO_NOT_EMIT_BYTECODE
+ VISIT_SEQ(c, stmt, s->v.If.body);
+ END_DO_NOT_EMIT_BYTECODE
+ if (s->v.If.orelse) {
+ VISIT_SEQ(c, stmt, s->v.If.orelse);
+ }
+ } else if (constant == 1) {
+ VISIT_SEQ(c, stmt, s->v.If.body);
+ if (s->v.If.orelse) {
+ BEGIN_DO_NOT_EMIT_BYTECODE
+ VISIT_SEQ(c, stmt, s->v.If.orelse);
+ END_DO_NOT_EMIT_BYTECODE
+ }
+ } else {
+ if (asdl_seq_LEN(s->v.If.orelse)) {
+ next = compiler_new_block(c);
+ if (next == NULL)
+ return 0;
+ }
+ else {
+ next = end;
+ }
+ if (!compiler_jump_if(c, s->v.If.test, next, 0)) {
+ return 0;
+ }
+ VISIT_SEQ(c, stmt, s->v.If.body);
+ if (asdl_seq_LEN(s->v.If.orelse)) {
+ ADDOP_JREL(c, JUMP_FORWARD, end);
+ compiler_use_next_block(c, next);
+ VISIT_SEQ(c, stmt, s->v.If.orelse);
+ }
+ }
+ compiler_use_next_block(c, end);
+ return 1;
+}
+
+static int
+compiler_for(struct compiler *c, stmt_ty s)
+{
+ basicblock *start, *cleanup, *end;
+
+ start = compiler_new_block(c);
+ cleanup = compiler_new_block(c);
+ end = compiler_new_block(c);
+ if (start == NULL || end == NULL || cleanup == NULL) {
+ return 0;
+ }
+ if (!compiler_push_fblock(c, FOR_LOOP, start, end, NULL)) {
+ return 0;
+ }
+ VISIT(c, expr, s->v.For.iter);
+ ADDOP(c, GET_ITER);
+ compiler_use_next_block(c, start);
+ ADDOP_JREL(c, FOR_ITER, cleanup);
+ VISIT(c, expr, s->v.For.target);
+ VISIT_SEQ(c, stmt, s->v.For.body);
+ ADDOP_JABS(c, JUMP_ABSOLUTE, start);
+ compiler_use_next_block(c, cleanup);
+
+ compiler_pop_fblock(c, FOR_LOOP, start);
+
+ VISIT_SEQ(c, stmt, s->v.For.orelse);
+ compiler_use_next_block(c, end);
+ return 1;
+}
+
+
+static int
+compiler_async_for(struct compiler *c, stmt_ty s)
+{
+ basicblock *start, *except, *end;
+ if (IS_TOP_LEVEL_AWAIT(c)){
+ c->u->u_ste->ste_coroutine = 1;
+ } else if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION) {
+ return compiler_error(c, "'async for' outside async function");
+ }
+
+ start = compiler_new_block(c);
+ except = compiler_new_block(c);
+ end = compiler_new_block(c);
+
+ if (start == NULL || except == NULL || end == NULL) {
+ return 0;
+ }
+ VISIT(c, expr, s->v.AsyncFor.iter);
+ ADDOP(c, GET_AITER);
+
+ compiler_use_next_block(c, start);
+ if (!compiler_push_fblock(c, FOR_LOOP, start, end, NULL)) {
+ return 0;
+ }
+ /* SETUP_FINALLY to guard the __anext__ call */
+ ADDOP_JREL(c, SETUP_FINALLY, except);
+ ADDOP(c, GET_ANEXT);
+ ADDOP_LOAD_CONST(c, Py_None);
+ ADDOP(c, YIELD_FROM);
+ ADDOP(c, POP_BLOCK); /* for SETUP_FINALLY */
+
+ /* Success block for __anext__ */
+ VISIT(c, expr, s->v.AsyncFor.target);
+ VISIT_SEQ(c, stmt, s->v.AsyncFor.body);
+ ADDOP_JABS(c, JUMP_ABSOLUTE, start);
+
+ compiler_pop_fblock(c, FOR_LOOP, start);
+
+ /* Except block for __anext__ */
+ compiler_use_next_block(c, except);
+
+ /* We don't want to trace the END_ASYNC_FOR, so make sure
+ * that it has the same lineno as the following instruction. */
+ if (asdl_seq_LEN(s->v.For.orelse)) {
+ SET_LOC(c, (stmt_ty)asdl_seq_GET(s->v.For.orelse, 0));
+ }
+ ADDOP(c, END_ASYNC_FOR);
+
+ /* `else` block */
+ VISIT_SEQ(c, stmt, s->v.For.orelse);
+
+ compiler_use_next_block(c, end);
+
+ return 1;
+}
+
+static int
+compiler_while(struct compiler *c, stmt_ty s)
+{
+ basicblock *loop, *orelse, *end, *anchor = NULL;
+ int constant = expr_constant(s->v.While.test);
+
+ if (constant == 0) {
+ BEGIN_DO_NOT_EMIT_BYTECODE
+ // Push a dummy block so the VISIT_SEQ knows that we are
+ // inside a while loop so it can correctly evaluate syntax
+ // errors.
+ if (!compiler_push_fblock(c, WHILE_LOOP, NULL, NULL, NULL)) {
+ return 0;
+ }
+ VISIT_SEQ(c, stmt, s->v.While.body);
+ // Remove the dummy block now that is not needed.
+ compiler_pop_fblock(c, WHILE_LOOP, NULL);
+ END_DO_NOT_EMIT_BYTECODE
+ if (s->v.While.orelse) {
+ VISIT_SEQ(c, stmt, s->v.While.orelse);
+ }
+ return 1;
+ }
+ loop = compiler_new_block(c);
+ end = compiler_new_block(c);
+ if (constant == -1) {
+ anchor = compiler_new_block(c);
+ if (anchor == NULL)
+ return 0;
+ }
+ if (loop == NULL || end == NULL)
+ return 0;
+ if (s->v.While.orelse) {
+ orelse = compiler_new_block(c);
+ if (orelse == NULL)
+ return 0;
+ }
+ else
+ orelse = NULL;
+
+ compiler_use_next_block(c, loop);
+ if (!compiler_push_fblock(c, WHILE_LOOP, loop, end, NULL))
+ return 0;
+ if (constant == -1) {
+ if (!compiler_jump_if(c, s->v.While.test, anchor, 0))
+ return 0;
+ }
+ VISIT_SEQ(c, stmt, s->v.While.body);
+ ADDOP_JABS(c, JUMP_ABSOLUTE, loop);
+
+ /* XXX should the two POP instructions be in a separate block
+ if there is no else clause ?
+ */
+
+ if (constant == -1)
+ compiler_use_next_block(c, anchor);
+ compiler_pop_fblock(c, WHILE_LOOP, loop);
+
+ if (orelse != NULL) /* what if orelse is just pass? */
+ VISIT_SEQ(c, stmt, s->v.While.orelse);
+ compiler_use_next_block(c, end);
+
+ return 1;
+}
+
+static int
+compiler_return(struct compiler *c, stmt_ty s)
+{
+ int preserve_tos = ((s->v.Return.value != NULL) &&
+ (s->v.Return.value->kind != Constant_kind));
+ if (c->u->u_ste->ste_type != FunctionBlock)
+ return compiler_error(c, "'return' outside function");
+ if (s->v.Return.value != NULL &&
+ c->u->u_ste->ste_coroutine && c->u->u_ste->ste_generator)
+ {
+ return compiler_error(
+ c, "'return' with value in async generator");
+ }
+ if (preserve_tos) {
+ VISIT(c, expr, s->v.Return.value);
+ }
+ if (!compiler_unwind_fblock_stack(c, preserve_tos, NULL))
+ return 0;
+ if (s->v.Return.value == NULL) {
+ ADDOP_LOAD_CONST(c, Py_None);
+ }
+ else if (!preserve_tos) {
+ VISIT(c, expr, s->v.Return.value);
+ }
+ ADDOP(c, RETURN_VALUE);
+
+ return 1;
+}
+
+static int
+compiler_break(struct compiler *c)
+{
+ struct fblockinfo *loop = NULL;
+ if (!compiler_unwind_fblock_stack(c, 0, &loop)) {
+ return 0;
+ }
+ if (loop == NULL) {
+ return compiler_error(c, "'break' outside loop");
+ }
+ if (!compiler_unwind_fblock(c, loop, 0)) {
+ return 0;
+ }
+ ADDOP_JABS(c, JUMP_ABSOLUTE, loop->fb_exit);
+ return 1;
+}
+
+static int
+compiler_continue(struct compiler *c)
+{
+ struct fblockinfo *loop = NULL;
+ if (!compiler_unwind_fblock_stack(c, 0, &loop)) {
+ return 0;
+ }
+ if (loop == NULL) {
+ return compiler_error(c, "'continue' not properly in loop");
+ }
+ ADDOP_JABS(c, JUMP_ABSOLUTE, loop->fb_block);
+ return 1;
+}
+
+
+/* Code generated for "try: <body> finally: <finalbody>" is as follows:
+
+ SETUP_FINALLY L
+ <code for body>
+ POP_BLOCK
+ <code for finalbody>
+ JUMP E
+ L:
+ <code for finalbody>
+ E:
+
+ The special instructions use the block stack. Each block
+ stack entry contains the instruction that created it (here
+ SETUP_FINALLY), the level of the value stack at the time the
+ block stack entry was created, and a label (here L).
+
+ SETUP_FINALLY:
+ Pushes the current value stack level and the label
+ onto the block stack.
+ POP_BLOCK:
+ Pops en entry from the block stack.
+
+ The block stack is unwound when an exception is raised:
+ when a SETUP_FINALLY entry is found, the raised and the caught
+ exceptions are pushed onto the value stack (and the exception
+ condition is cleared), and the interpreter jumps to the label
+ gotten from the block stack.
+*/
+
+static int
+compiler_try_finally(struct compiler *c, stmt_ty s)
+{
+ basicblock *body, *end, *exit;
+
+ body = compiler_new_block(c);
+ end = compiler_new_block(c);
+ exit = compiler_new_block(c);
+ if (body == NULL || end == NULL || exit == NULL)
+ return 0;
+
+ /* `try` block */
+ ADDOP_JREL(c, SETUP_FINALLY, end);
+ compiler_use_next_block(c, body);
+ if (!compiler_push_fblock(c, FINALLY_TRY, body, end, s->v.Try.finalbody))
+ return 0;
+ if (s->v.Try.handlers && asdl_seq_LEN(s->v.Try.handlers)) {
+ if (!compiler_try_except(c, s))
+ return 0;
+ }
+ else {
+ VISIT_SEQ(c, stmt, s->v.Try.body);
+ }
+ ADDOP(c, POP_BLOCK);
+ compiler_pop_fblock(c, FINALLY_TRY, body);
+ VISIT_SEQ(c, stmt, s->v.Try.finalbody);
+ ADDOP_JREL(c, JUMP_FORWARD, exit);
+ /* `finally` block */
+ compiler_use_next_block(c, end);
+ if (!compiler_push_fblock(c, FINALLY_END, end, NULL, NULL))
+ return 0;
+ VISIT_SEQ(c, stmt, s->v.Try.finalbody);
+ compiler_pop_fblock(c, FINALLY_END, end);
+ ADDOP(c, RERAISE);
+ compiler_use_next_block(c, exit);
+ return 1;
+}
+
+/*
+ Code generated for "try: S except E1 as V1: S1 except E2 as V2: S2 ...":
+ (The contents of the value stack is shown in [], with the top
+ at the right; 'tb' is trace-back info, 'val' the exception's
+ associated value, and 'exc' the exception.)
+
+ Value stack Label Instruction Argument
+ [] SETUP_FINALLY L1
+ [] <code for S>
+ [] POP_BLOCK
+ [] JUMP_FORWARD L0
+
+ [tb, val, exc] L1: DUP )
+ [tb, val, exc, exc] <evaluate E1> )
+ [tb, val, exc, exc, E1] JUMP_IF_NOT_EXC_MATCH L2 ) only if E1
+ [tb, val, exc] POP
+ [tb, val] <assign to V1> (or POP if no V1)
+ [tb] POP
+ [] <code for S1>
+ JUMP_FORWARD L0
+
+ [tb, val, exc] L2: DUP
+ .............................etc.......................
+
+ [tb, val, exc] Ln+1: RERAISE # re-raise exception
+
+ [] L0: <next statement>
+
+ Of course, parts are not generated if Vi or Ei is not present.
+*/
+static int
+compiler_try_except(struct compiler *c, stmt_ty s)
+{
+ basicblock *body, *orelse, *except, *end;
+ Py_ssize_t i, n;
+
+ body = compiler_new_block(c);
+ except = compiler_new_block(c);
+ orelse = compiler_new_block(c);
+ end = compiler_new_block(c);
+ if (body == NULL || except == NULL || orelse == NULL || end == NULL)
+ return 0;
+ ADDOP_JREL(c, SETUP_FINALLY, except);
+ compiler_use_next_block(c, body);
+ if (!compiler_push_fblock(c, TRY_EXCEPT, body, NULL, NULL))
+ return 0;
+ VISIT_SEQ(c, stmt, s->v.Try.body);
+ ADDOP(c, POP_BLOCK);
+ compiler_pop_fblock(c, TRY_EXCEPT, body);
+ ADDOP_JREL(c, JUMP_FORWARD, orelse);
+ n = asdl_seq_LEN(s->v.Try.handlers);
+ compiler_use_next_block(c, except);
+ /* Runtime will push a block here, so we need to account for that */
+ if (!compiler_push_fblock(c, EXCEPTION_HANDLER, NULL, NULL, NULL))
+ return 0;
+ for (i = 0; i < n; i++) {
+ excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
+ s->v.Try.handlers, i);
+ if (!handler->v.ExceptHandler.type && i < n-1)
+ return compiler_error(c, "default 'except:' must be last");
+ SET_LOC(c, handler);
+ except = compiler_new_block(c);
+ if (except == NULL)
+ return 0;
+ if (handler->v.ExceptHandler.type) {
+ ADDOP(c, DUP_TOP);
+ VISIT(c, expr, handler->v.ExceptHandler.type);
+ ADDOP_JABS(c, JUMP_IF_NOT_EXC_MATCH, except);
+ }
+ ADDOP(c, POP_TOP);
+ if (handler->v.ExceptHandler.name) {
+ basicblock *cleanup_end, *cleanup_body;
+
+ cleanup_end = compiler_new_block(c);
+ cleanup_body = compiler_new_block(c);
+ if (cleanup_end == NULL || cleanup_body == NULL) {
+ return 0;
+ }
+
+ compiler_nameop(c, handler->v.ExceptHandler.name, Store);
+ ADDOP(c, POP_TOP);
+
+ /*
+ try:
+ # body
+ except type as name:
+ try:
+ # body
+ finally:
+ name = None # in case body contains "del name"
+ del name
+ */
+
+ /* second try: */
+ ADDOP_JREL(c, SETUP_FINALLY, cleanup_end);
+ compiler_use_next_block(c, cleanup_body);
+ if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NULL, handler->v.ExceptHandler.name))
+ return 0;
+
+ /* second # body */
+ VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
+ compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body);
+ ADDOP(c, POP_BLOCK);
+ ADDOP(c, POP_EXCEPT);
+ /* name = None; del name */
+ ADDOP_LOAD_CONST(c, Py_None);
+ compiler_nameop(c, handler->v.ExceptHandler.name, Store);
+ compiler_nameop(c, handler->v.ExceptHandler.name, Del);
+ ADDOP_JREL(c, JUMP_FORWARD, end);
+
+ /* except: */
+ compiler_use_next_block(c, cleanup_end);
+
+ /* name = None; del name */
+ ADDOP_LOAD_CONST(c, Py_None);
+ compiler_nameop(c, handler->v.ExceptHandler.name, Store);
+ compiler_nameop(c, handler->v.ExceptHandler.name, Del);
+
+ ADDOP(c, RERAISE);
+ }
+ else {
+ basicblock *cleanup_body;
+
+ cleanup_body = compiler_new_block(c);
+ if (!cleanup_body)
+ return 0;
+
+ ADDOP(c, POP_TOP);
+ ADDOP(c, POP_TOP);
+ compiler_use_next_block(c, cleanup_body);
+ if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NULL, NULL))
+ return 0;
+ VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
+ compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body);
+ ADDOP(c, POP_EXCEPT);
+ ADDOP_JREL(c, JUMP_FORWARD, end);
+ }
+ compiler_use_next_block(c, except);
+ }
+ compiler_pop_fblock(c, EXCEPTION_HANDLER, NULL);
+ ADDOP(c, RERAISE);
+ compiler_use_next_block(c, orelse);
+ VISIT_SEQ(c, stmt, s->v.Try.orelse);
+ compiler_use_next_block(c, end);
+ return 1;
+}
+
+static int
+compiler_try(struct compiler *c, stmt_ty s) {
+ if (s->v.Try.finalbody && asdl_seq_LEN(s->v.Try.finalbody))
+ return compiler_try_finally(c, s);
+ else
+ return compiler_try_except(c, s);
+}
+
+
+static int
+compiler_import_as(struct compiler *c, identifier name, identifier asname)
+{
+ /* The IMPORT_NAME opcode was already generated. This function
+ merely needs to bind the result to a name.
+
+ If there is a dot in name, we need to split it and emit a
+ IMPORT_FROM for each name.
+ */
+ Py_ssize_t len = PyUnicode_GET_LENGTH(name);
+ Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0, len, 1);
+ if (dot == -2)
+ return 0;
+ if (dot != -1) {
+ /* Consume the base module name to get the first attribute */
+ while (1) {
+ Py_ssize_t pos = dot + 1;
+ PyObject *attr;
+ dot = PyUnicode_FindChar(name, '.', pos, len, 1);
+ if (dot == -2)
+ return 0;
+ attr = PyUnicode_Substring(name, pos, (dot != -1) ? dot : len);
+ if (!attr)
+ return 0;
+ ADDOP_N(c, IMPORT_FROM, attr, names);
+ if (dot == -1) {
+ break;
+ }
+ ADDOP(c, ROT_TWO);
+ ADDOP(c, POP_TOP);
+ }
+ if (!compiler_nameop(c, asname, Store)) {
+ return 0;
+ }
+ ADDOP(c, POP_TOP);
+ return 1;
+ }
+ return compiler_nameop(c, asname, Store);
+}
+
+static int
+compiler_import(struct compiler *c, stmt_ty s)
+{
+ /* The Import node stores a module name like a.b.c as a single
+ string. This is convenient for all cases except
+ import a.b.c as d
+ where we need to parse that string to extract the individual
+ module names.
+ XXX Perhaps change the representation to make this case simpler?
+ */
+ Py_ssize_t i, n = asdl_seq_LEN(s->v.Import.names);
+
+ for (i = 0; i < n; i++) {
+ alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i);
+ int r;
+
+ ADDOP_LOAD_CONST(c, _PyLong_Zero);
+ ADDOP_LOAD_CONST(c, Py_None);
+ ADDOP_NAME(c, IMPORT_NAME, alias->name, names);
+
+ if (alias->asname) {
+ r = compiler_import_as(c, alias->name, alias->asname);
+ if (!r)
+ return r;
+ }
+ else {
+ identifier tmp = alias->name;
+ Py_ssize_t dot = PyUnicode_FindChar(
+ alias->name, '.', 0, PyUnicode_GET_LENGTH(alias->name), 1);
+ if (dot != -1) {
+ tmp = PyUnicode_Substring(alias->name, 0, dot);
+ if (tmp == NULL)
+ return 0;
+ }
+ r = compiler_nameop(c, tmp, Store);
+ if (dot != -1) {
+ Py_DECREF(tmp);
+ }
+ if (!r)
+ return r;
+ }
+ }
+ return 1;
+}
+
+static int
+compiler_from_import(struct compiler *c, stmt_ty s)
+{
+ Py_ssize_t i, n = asdl_seq_LEN(s->v.ImportFrom.names);
+ PyObject *names;
+ static PyObject *empty_string;
+
+ if (!empty_string) {
+ empty_string = PyUnicode_FromString("");
+ if (!empty_string)
+ return 0;
+ }
+
+ ADDOP_LOAD_CONST_NEW(c, PyLong_FromLong(s->v.ImportFrom.level));
+
+ names = PyTuple_New(n);
+ if (!names)
+ return 0;
+
+ /* build up the names */
+ for (i = 0; i < n; i++) {
+ alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
+ Py_INCREF(alias->name);
+ PyTuple_SET_ITEM(names, i, alias->name);
+ }
+
+ if (s->lineno > c->c_future->ff_lineno && s->v.ImportFrom.module &&
+ _PyUnicode_EqualToASCIIString(s->v.ImportFrom.module, "__future__")) {
+ Py_DECREF(names);
+ return compiler_error(c, "from __future__ imports must occur "
+ "at the beginning of the file");
+ }
+ ADDOP_LOAD_CONST_NEW(c, names);
+
+ if (s->v.ImportFrom.module) {
+ ADDOP_NAME(c, IMPORT_NAME, s->v.ImportFrom.module, names);
+ }
+ else {
+ ADDOP_NAME(c, IMPORT_NAME, empty_string, names);
+ }
+ for (i = 0; i < n; i++) {
+ alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
+ identifier store_name;
+
+ if (i == 0 && PyUnicode_READ_CHAR(alias->name, 0) == '*') {
+ assert(n == 1);
+ ADDOP(c, IMPORT_STAR);
+ return 1;
+ }
+
+ ADDOP_NAME(c, IMPORT_FROM, alias->name, names);
+ store_name = alias->name;
+ if (alias->asname)
+ store_name = alias->asname;
+
+ if (!compiler_nameop(c, store_name, Store)) {
+ return 0;
+ }
+ }
+ /* remove imported module */
+ ADDOP(c, POP_TOP);
+ return 1;
+}
+
+static int
+compiler_assert(struct compiler *c, stmt_ty s)
+{
+ basicblock *end;
+
+ if (c->c_optimize)
+ return 1;
+ if (s->v.Assert.test->kind == Tuple_kind &&
+ asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0)
+ {
+ if (!compiler_warn(c, "assertion is always true, "
+ "perhaps remove parentheses?"))
+ {
+ return 0;
+ }
+ }
+ end = compiler_new_block(c);
+ if (end == NULL)
+ return 0;
+ if (!compiler_jump_if(c, s->v.Assert.test, end, 1))
+ return 0;
+ ADDOP(c, LOAD_ASSERTION_ERROR);
+ if (s->v.Assert.msg) {
+ VISIT(c, expr, s->v.Assert.msg);
+ ADDOP_I(c, CALL_FUNCTION, 1);
+ }
+ ADDOP_I(c, RAISE_VARARGS, 1);
+ compiler_use_next_block(c, end);
+ return 1;
+}
+
+static int
+compiler_visit_stmt_expr(struct compiler *c, expr_ty value)
+{
+ if (c->c_interactive && c->c_nestlevel <= 1) {
+ VISIT(c, expr, value);
+ ADDOP(c, PRINT_EXPR);
+ return 1;
+ }
+
+ if (value->kind == Constant_kind) {
+ /* ignore constant statement */
+ return 1;
+ }
+
+ VISIT(c, expr, value);
+ ADDOP(c, POP_TOP);
+ return 1;
+}
+
+static int
+compiler_visit_stmt(struct compiler *c, stmt_ty s)
+{
+ Py_ssize_t i, n;
+
+ /* Always assign a lineno to the next instruction for a stmt. */
+ SET_LOC(c, s);
+
+ switch (s->kind) {
+ case FunctionDef_kind:
+ return compiler_function(c, s, 0);
+ case ClassDef_kind:
+ return compiler_class(c, s);
+ case Return_kind:
+ return compiler_return(c, s);
+ case Delete_kind:
+ VISIT_SEQ(c, expr, s->v.Delete.targets)
+ break;
+ case Assign_kind:
+ n = asdl_seq_LEN(s->v.Assign.targets);
+ VISIT(c, expr, s->v.Assign.value);
+ for (i = 0; i < n; i++) {
+ if (i < n - 1)
+ ADDOP(c, DUP_TOP);
+ VISIT(c, expr,
+ (expr_ty)asdl_seq_GET(s->v.Assign.targets, i));
+ }
+ break;
+ case AugAssign_kind:
+ return compiler_augassign(c, s);
+ case AnnAssign_kind:
+ return compiler_annassign(c, s);
+ case For_kind:
+ return compiler_for(c, s);
+ case While_kind:
+ return compiler_while(c, s);
+ case If_kind:
+ return compiler_if(c, s);
+ case Raise_kind:
+ n = 0;
+ if (s->v.Raise.exc) {
+ VISIT(c, expr, s->v.Raise.exc);
+ n++;
+ if (s->v.Raise.cause) {
+ VISIT(c, expr, s->v.Raise.cause);
+ n++;
+ }
+ }
+ ADDOP_I(c, RAISE_VARARGS, (int)n);
+ break;
+ case Try_kind:
+ return compiler_try(c, s);
+ case Assert_kind:
+ return compiler_assert(c, s);
+ case Import_kind:
+ return compiler_import(c, s);
+ case ImportFrom_kind:
+ return compiler_from_import(c, s);
+ case Global_kind:
+ case Nonlocal_kind:
+ break;
+ case Expr_kind:
+ return compiler_visit_stmt_expr(c, s->v.Expr.value);
+ case Pass_kind:
+ break;
+ case Break_kind:
+ return compiler_break(c);
+ case Continue_kind:
+ return compiler_continue(c);
+ case With_kind:
+ return compiler_with(c, s, 0);
+ case AsyncFunctionDef_kind:
+ return compiler_function(c, s, 1);
+ case AsyncWith_kind:
+ return compiler_async_with(c, s, 0);
+ case AsyncFor_kind:
+ return compiler_async_for(c, s);
+ }
+
+ return 1;
+}
+
+static int
+unaryop(unaryop_ty op)
+{
+ switch (op) {
+ case Invert:
+ return UNARY_INVERT;
+ case Not:
+ return UNARY_NOT;
+ case UAdd:
+ return UNARY_POSITIVE;
+ case USub:
+ return UNARY_NEGATIVE;
+ default:
+ PyErr_Format(PyExc_SystemError,
+ "unary op %d should not be possible", op);
+ return 0;
+ }
+}
+
+static int
+binop(operator_ty op)
+{
+ switch (op) {
+ case Add:
+ return BINARY_ADD;
+ case Sub:
+ return BINARY_SUBTRACT;
+ case Mult:
+ return BINARY_MULTIPLY;
+ case MatMult:
+ return BINARY_MATRIX_MULTIPLY;
+ case Div:
+ return BINARY_TRUE_DIVIDE;
+ case Mod:
+ return BINARY_MODULO;
+ case Pow:
+ return BINARY_POWER;
+ case LShift:
+ return BINARY_LSHIFT;
+ case RShift:
+ return BINARY_RSHIFT;
+ case BitOr:
+ return BINARY_OR;
+ case BitXor:
+ return BINARY_XOR;
+ case BitAnd:
+ return BINARY_AND;
+ case FloorDiv:
+ return BINARY_FLOOR_DIVIDE;
+ default:
+ PyErr_Format(PyExc_SystemError,
+ "binary op %d should not be possible", op);
+ return 0;
+ }
+}
+
+static int
+inplace_binop(operator_ty op)
+{
+ switch (op) {
+ case Add:
+ return INPLACE_ADD;
+ case Sub:
+ return INPLACE_SUBTRACT;
+ case Mult:
+ return INPLACE_MULTIPLY;
+ case MatMult:
+ return INPLACE_MATRIX_MULTIPLY;
+ case Div:
+ return INPLACE_TRUE_DIVIDE;
+ case Mod:
+ return INPLACE_MODULO;
+ case Pow:
+ return INPLACE_POWER;
+ case LShift:
+ return INPLACE_LSHIFT;
+ case RShift:
+ return INPLACE_RSHIFT;
+ case BitOr:
+ return INPLACE_OR;
+ case BitXor:
+ return INPLACE_XOR;
+ case BitAnd:
+ return INPLACE_AND;
+ case FloorDiv:
+ return INPLACE_FLOOR_DIVIDE;
+ default:
+ PyErr_Format(PyExc_SystemError,
+ "inplace binary op %d should not be possible", op);
+ return 0;
+ }
+}
+
+static int
+compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
+{
+ int op, scope;
+ Py_ssize_t arg;
+ enum { OP_FAST, OP_GLOBAL, OP_DEREF, OP_NAME } optype;
+
+ PyObject *dict = c->u->u_names;
+ PyObject *mangled;
+
+ assert(!_PyUnicode_EqualToASCIIString(name, "None") &&
+ !_PyUnicode_EqualToASCIIString(name, "True") &&
+ !_PyUnicode_EqualToASCIIString(name, "False"));
+
+ if (forbidden_name(c, name, ctx))
+ return 0;
+
+ mangled = _Py_Mangle(c->u->u_private, name);
+ if (!mangled)
+ return 0;
+
+ op = 0;
+ optype = OP_NAME;
+ scope = PyST_GetScope(c->u->u_ste, mangled);
+ switch (scope) {
+ case FREE:
+ dict = c->u->u_freevars;
+ optype = OP_DEREF;
+ break;
+ case CELL:
+ dict = c->u->u_cellvars;
+ optype = OP_DEREF;
+ break;
+ case LOCAL:
+ if (c->u->u_ste->ste_type == FunctionBlock)
+ optype = OP_FAST;
+ break;
+ case GLOBAL_IMPLICIT:
+ if (c->u->u_ste->ste_type == FunctionBlock)
+ optype = OP_GLOBAL;
+ break;
+ case GLOBAL_EXPLICIT:
+ optype = OP_GLOBAL;
+ break;
+ default:
+ /* scope can be 0 */
+ break;
+ }
+
+ /* XXX Leave assert here, but handle __doc__ and the like better */
+ assert(scope || PyUnicode_READ_CHAR(name, 0) == '_');
+
+ switch (optype) {
+ case OP_DEREF:
+ switch (ctx) {
+ case Load:
+ op = (c->u->u_ste->ste_type == ClassBlock) ? LOAD_CLASSDEREF : LOAD_DEREF;
+ break;
+ case Store: op = STORE_DEREF; break;
+ case Del: op = DELETE_DEREF; break;
+ }
+ break;
+ case OP_FAST:
+ switch (ctx) {
+ case Load: op = LOAD_FAST; break;
+ case Store: op = STORE_FAST; break;
+ case Del: op = DELETE_FAST; break;
+ }
+ ADDOP_N(c, op, mangled, varnames);
+ return 1;
+ case OP_GLOBAL:
+ switch (ctx) {
+ case Load: op = LOAD_GLOBAL; break;
+ case Store: op = STORE_GLOBAL; break;
+ case Del: op = DELETE_GLOBAL; break;
+ }
+ break;
+ case OP_NAME:
+ switch (ctx) {
+ case Load: op = LOAD_NAME; break;
+ case Store: op = STORE_NAME; break;
+ case Del: op = DELETE_NAME; break;
+ }
+ break;
+ }
+
+ assert(op);
+ arg = compiler_add_o(dict, mangled);
+ Py_DECREF(mangled);
+ if (arg < 0)
+ return 0;
+ return compiler_addop_i(c, op, arg);
+}
+
+static int
+compiler_boolop(struct compiler *c, expr_ty e)
+{
+ basicblock *end;
+ int jumpi;
+ Py_ssize_t i, n;
+ asdl_seq *s;
+
+ assert(e->kind == BoolOp_kind);
+ if (e->v.BoolOp.op == And)
+ jumpi = JUMP_IF_FALSE_OR_POP;
+ else
+ jumpi = JUMP_IF_TRUE_OR_POP;
+ end = compiler_new_block(c);
+ if (end == NULL)
+ return 0;
+ s = e->v.BoolOp.values;
+ n = asdl_seq_LEN(s) - 1;
+ assert(n >= 0);
+ for (i = 0; i < n; ++i) {
+ VISIT(c, expr, (expr_ty)asdl_seq_GET(s, i));
+ ADDOP_JABS(c, jumpi, end);
+ }
+ VISIT(c, expr, (expr_ty)asdl_seq_GET(s, n));
+ compiler_use_next_block(c, end);
+ return 1;
+}
+
+static int
+starunpack_helper(struct compiler *c, asdl_seq *elts, int pushed,
+ int build, int add, int extend, int tuple)
+{
+ Py_ssize_t n = asdl_seq_LEN(elts);
+ Py_ssize_t i, seen_star = 0;
+ if (n > 2 && are_all_items_const(elts, 0, n)) {
+ PyObject *folded = PyTuple_New(n);
+ if (folded == NULL) {
+ return 0;
+ }
+ PyObject *val;
+ for (i = 0; i < n; i++) {
+ val = ((expr_ty)asdl_seq_GET(elts, i))->v.Constant.value;
+ Py_INCREF(val);
+ PyTuple_SET_ITEM(folded, i, val);
+ }
+ if (tuple) {
+ ADDOP_LOAD_CONST_NEW(c, folded);
+ } else {
+ if (add == SET_ADD) {
+ Py_SETREF(folded, PyFrozenSet_New(folded));
+ if (folded == NULL) {
+ return 0;
+ }
+ }
+ ADDOP_I(c, build, pushed);
+ ADDOP_LOAD_CONST_NEW(c, folded);
+ ADDOP_I(c, extend, 1);
+ }
+ return 1;
+ }
+
+ for (i = 0; i < n; i++) {
+ expr_ty elt = asdl_seq_GET(elts, i);
+ if (elt->kind == Starred_kind) {
+ seen_star = 1;
+ }
+ }
+ if (seen_star) {
+ seen_star = 0;
+ for (i = 0; i < n; i++) {
+ expr_ty elt = asdl_seq_GET(elts, i);
+ if (elt->kind == Starred_kind) {
+ if (seen_star == 0) {
+ ADDOP_I(c, build, i+pushed);
+ seen_star = 1;
+ }
+ VISIT(c, expr, elt->v.Starred.value);
+ ADDOP_I(c, extend, 1);
+ }
+ else {
+ VISIT(c, expr, elt);
+ if (seen_star) {
+ ADDOP_I(c, add, 1);
+ }
+ }
+ }
+ assert(seen_star);
+ if (tuple) {
+ ADDOP(c, LIST_TO_TUPLE);
+ }
+ }
+ else {
+ for (i = 0; i < n; i++) {
+ expr_ty elt = asdl_seq_GET(elts, i);
+ VISIT(c, expr, elt);
+ }
+ if (tuple) {
+ ADDOP_I(c, BUILD_TUPLE, n+pushed);
+ } else {
+ ADDOP_I(c, build, n+pushed);
+ }
+ }
+ return 1;
+}
+
+static int
+assignment_helper(struct compiler *c, asdl_seq *elts)
+{
+ Py_ssize_t n = asdl_seq_LEN(elts);
+ Py_ssize_t i;
+ int seen_star = 0;
+ for (i = 0; i < n; i++) {
+ expr_ty elt = asdl_seq_GET(elts, i);
+ if (elt->kind == Starred_kind && !seen_star) {
+ if ((i >= (1 << 8)) ||
+ (n-i-1 >= (INT_MAX >> 8)))
+ return compiler_error(c,
+ "too many expressions in "
+ "star-unpacking assignment");
+ ADDOP_I(c, UNPACK_EX, (i + ((n-i-1) << 8)));
+ seen_star = 1;
+ }
+ else if (elt->kind == Starred_kind) {
+ return compiler_error(c,
+ "multiple starred expressions in assignment");
+ }
+ }
+ if (!seen_star) {
+ ADDOP_I(c, UNPACK_SEQUENCE, n);
+ }
+ for (i = 0; i < n; i++) {
+ expr_ty elt = asdl_seq_GET(elts, i);
+ VISIT(c, expr, elt->kind != Starred_kind ? elt : elt->v.Starred.value);
+ }
+ return 1;
+}
+
+static int
+compiler_list(struct compiler *c, expr_ty e)
+{
+ asdl_seq *elts = e->v.List.elts;
+ if (e->v.List.ctx == Store) {
+ return assignment_helper(c, elts);
+ }
+ else if (e->v.List.ctx == Load) {
+ return starunpack_helper(c, elts, 0, BUILD_LIST,
+ LIST_APPEND, LIST_EXTEND, 0);
+ }
+ else
+ VISIT_SEQ(c, expr, elts);
+ return 1;
+}
+
+static int
+compiler_tuple(struct compiler *c, expr_ty e)
+{
+ asdl_seq *elts = e->v.Tuple.elts;
+ if (e->v.Tuple.ctx == Store) {
+ return assignment_helper(c, elts);
+ }
+ else if (e->v.Tuple.ctx == Load) {
+ return starunpack_helper(c, elts, 0, BUILD_LIST,
+ LIST_APPEND, LIST_EXTEND, 1);
+ }
+ else
+ VISIT_SEQ(c, expr, elts);
+ return 1;
+}
+
+static int
+compiler_set(struct compiler *c, expr_ty e)
+{
+ return starunpack_helper(c, e->v.Set.elts, 0, BUILD_SET,
+ SET_ADD, SET_UPDATE, 0);
+}
+
+static int
+are_all_items_const(asdl_seq *seq, Py_ssize_t begin, Py_ssize_t end)
+{
+ Py_ssize_t i;
+ for (i = begin; i < end; i++) {
+ expr_ty key = (expr_ty)asdl_seq_GET(seq, i);
+ if (key == NULL || key->kind != Constant_kind)
+ return 0;
+ }
+ return 1;
+}
+
+static int
+compiler_subdict(struct compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end)
+{
+ Py_ssize_t i, n = end - begin;
+ PyObject *keys, *key;
+ if (n > 1 && are_all_items_const(e->v.Dict.keys, begin, end)) {
+ for (i = begin; i < end; i++) {
+ VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
+ }
+ keys = PyTuple_New(n);
+ if (keys == NULL) {
+ return 0;
+ }
+ for (i = begin; i < end; i++) {
+ key = ((expr_ty)asdl_seq_GET(e->v.Dict.keys, i))->v.Constant.value;
+ Py_INCREF(key);
+ PyTuple_SET_ITEM(keys, i - begin, key);
+ }
+ ADDOP_LOAD_CONST_NEW(c, keys);
+ ADDOP_I(c, BUILD_CONST_KEY_MAP, n);
+ }
+ else {
+ for (i = begin; i < end; i++) {
+ VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.keys, i));
+ VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
+ }
+ ADDOP_I(c, BUILD_MAP, n);
+ }
+ return 1;
+}
+
+static int
+compiler_dict(struct compiler *c, expr_ty e)
+{
+ Py_ssize_t i, n, elements;
+ int have_dict;
+ int is_unpacking = 0;
+ n = asdl_seq_LEN(e->v.Dict.values);
+ have_dict = 0;
+ elements = 0;
+ for (i = 0; i < n; i++) {
+ is_unpacking = (expr_ty)asdl_seq_GET(e->v.Dict.keys, i) == NULL;
+ if (is_unpacking) {
+ if (elements) {
+ if (!compiler_subdict(c, e, i - elements, i)) {
+ return 0;
+ }
+ if (have_dict) {
+ ADDOP_I(c, DICT_UPDATE, 1);
+ }
+ have_dict = 1;
+ elements = 0;
+ }
+ if (have_dict == 0) {
+ ADDOP_I(c, BUILD_MAP, 0);
+ have_dict = 1;
+ }
+ VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
+ ADDOP_I(c, DICT_UPDATE, 1);
+ }
+ else {
+ if (elements == 0xFFFF) {
+ if (!compiler_subdict(c, e, i - elements, i + 1)) {
+ return 0;
+ }
+ if (have_dict) {
+ ADDOP_I(c, DICT_UPDATE, 1);
+ }
+ have_dict = 1;
+ elements = 0;
+ }
+ else {
+ elements++;
+ }
+ }
+ }
+ if (elements) {
+ if (!compiler_subdict(c, e, n - elements, n)) {
+ return 0;
+ }
+ if (have_dict) {
+ ADDOP_I(c, DICT_UPDATE, 1);
+ }
+ have_dict = 1;
+ }
+ if (!have_dict) {
+ ADDOP_I(c, BUILD_MAP, 0);
+ }
+ return 1;
+}
+
+static int
+compiler_compare(struct compiler *c, expr_ty e)
+{
+ Py_ssize_t i, n;
+
+ if (!check_compare(c, e)) {
+ return 0;
+ }
+ VISIT(c, expr, e->v.Compare.left);
+ assert(asdl_seq_LEN(e->v.Compare.ops) > 0);
+ n = asdl_seq_LEN(e->v.Compare.ops) - 1;
+ if (n == 0) {
+ VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, 0));
+ ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, 0));
+ }
+ else {
+ basicblock *cleanup = compiler_new_block(c);
+ if (cleanup == NULL)
+ return 0;
+ for (i = 0; i < n; i++) {
+ VISIT(c, expr,
+ (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
+ ADDOP(c, DUP_TOP);
+ ADDOP(c, ROT_THREE);
+ ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, i));
+ ADDOP_JABS(c, JUMP_IF_FALSE_OR_POP, cleanup);
+ NEXT_BLOCK(c);
+ }
+ VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n));
+ ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, n));
+ basicblock *end = compiler_new_block(c);
+ if (end == NULL)
+ return 0;
+ ADDOP_JREL(c, JUMP_FORWARD, end);
+ compiler_use_next_block(c, cleanup);
+ ADDOP(c, ROT_TWO);
+ ADDOP(c, POP_TOP);
+ compiler_use_next_block(c, end);
+ }
+ return 1;
+}
+
+static PyTypeObject *
+infer_type(expr_ty e)
+{
+ switch (e->kind) {
+ case Tuple_kind:
+ return &PyTuple_Type;
+ case List_kind:
+ case ListComp_kind:
+ return &PyList_Type;
+ case Dict_kind:
+ case DictComp_kind:
+ return &PyDict_Type;
+ case Set_kind:
+ case SetComp_kind:
+ return &PySet_Type;
+ case GeneratorExp_kind:
+ return &PyGen_Type;
+ case Lambda_kind:
+ return &PyFunction_Type;
+ case JoinedStr_kind:
+ case FormattedValue_kind:
+ return &PyUnicode_Type;
+ case Constant_kind:
+ return Py_TYPE(e->v.Constant.value);
+ default:
+ return NULL;
+ }
+}
+
+static int
+check_caller(struct compiler *c, expr_ty e)
+{
+ switch (e->kind) {
+ case Constant_kind:
+ case Tuple_kind:
+ case List_kind:
+ case ListComp_kind:
+ case Dict_kind:
+ case DictComp_kind:
+ case Set_kind:
+ case SetComp_kind:
+ case GeneratorExp_kind:
+ case JoinedStr_kind:
+ case FormattedValue_kind:
+ return compiler_warn(c, "'%.200s' object is not callable; "
+ "perhaps you missed a comma?",
+ infer_type(e)->tp_name);
+ default:
+ return 1;
+ }
+}
+
+static int
+check_subscripter(struct compiler *c, expr_ty e)
+{
+ PyObject *v;
+
+ switch (e->kind) {
+ case Constant_kind:
+ v = e->v.Constant.value;
+ if (!(v == Py_None || v == Py_Ellipsis ||
+ PyLong_Check(v) || PyFloat_Check(v) || PyComplex_Check(v) ||
+ PyAnySet_Check(v)))
+ {
+ return 1;
+ }
+ /* fall through */
+ case Set_kind:
+ case SetComp_kind:
+ case GeneratorExp_kind:
+ case Lambda_kind:
+ return compiler_warn(c, "'%.200s' object is not subscriptable; "
+ "perhaps you missed a comma?",
+ infer_type(e)->tp_name);
+ default:
+ return 1;
+ }
+}
+
+static int
+check_index(struct compiler *c, expr_ty e, expr_ty s)
+{
+ PyObject *v;
+
+ PyTypeObject *index_type = infer_type(s);
+ if (index_type == NULL
+ || PyType_FastSubclass(index_type, Py_TPFLAGS_LONG_SUBCLASS)
+ || index_type == &PySlice_Type) {
+ return 1;
+ }
+
+ switch (e->kind) {
+ case Constant_kind:
+ v = e->v.Constant.value;
+ if (!(PyUnicode_Check(v) || PyBytes_Check(v) || PyTuple_Check(v))) {
+ return 1;
+ }
+ /* fall through */
+ case Tuple_kind:
+ case List_kind:
+ case ListComp_kind:
+ case JoinedStr_kind:
+ case FormattedValue_kind:
+ return compiler_warn(c, "%.200s indices must be integers or slices, "
+ "not %.200s; "
+ "perhaps you missed a comma?",
+ infer_type(e)->tp_name,
+ index_type->tp_name);
+ default:
+ return 1;
+ }
+}
+
+// Return 1 if the method call was optimized, -1 if not, and 0 on error.
+static int
+maybe_optimize_method_call(struct compiler *c, expr_ty e)
+{
+ Py_ssize_t argsl, i;
+ expr_ty meth = e->v.Call.func;
+ asdl_seq *args = e->v.Call.args;
+
+ /* Check that the call node is an attribute access, and that
+ the call doesn't have keyword parameters. */
+ if (meth->kind != Attribute_kind || meth->v.Attribute.ctx != Load ||
+ asdl_seq_LEN(e->v.Call.keywords))
+ return -1;
+
+ /* Check that there are no *varargs types of arguments. */
+ argsl = asdl_seq_LEN(args);
+ for (i = 0; i < argsl; i++) {
+ expr_ty elt = asdl_seq_GET(args, i);
+ if (elt->kind == Starred_kind) {
+ return -1;
+ }
+ }
+
+ /* Alright, we can optimize the code. */
+ VISIT(c, expr, meth->v.Attribute.value);
+ ADDOP_NAME(c, LOAD_METHOD, meth->v.Attribute.attr, names);
+ VISIT_SEQ(c, expr, e->v.Call.args);
+ ADDOP_I(c, CALL_METHOD, asdl_seq_LEN(e->v.Call.args));
+ return 1;
+}
+
+static int
+validate_keywords(struct compiler *c, asdl_seq *keywords)
+{
+ Py_ssize_t nkeywords = asdl_seq_LEN(keywords);
+ for (Py_ssize_t i = 0; i < nkeywords; i++) {
+ keyword_ty key = ((keyword_ty)asdl_seq_GET(keywords, i));
+ if (key->arg == NULL) {
+ continue;
+ }
+ if (forbidden_name(c, key->arg, Store)) {
+ return -1;
+ }
+ for (Py_ssize_t j = i + 1; j < nkeywords; j++) {
+ keyword_ty other = ((keyword_ty)asdl_seq_GET(keywords, j));
+ if (other->arg && !PyUnicode_Compare(key->arg, other->arg)) {
+ PyObject *msg = PyUnicode_FromFormat("keyword argument repeated: %U", key->arg);
+ if (msg == NULL) {
+ return -1;
+ }
+ c->u->u_col_offset = other->col_offset;
+ compiler_error(c, PyUnicode_AsUTF8(msg));
+ Py_DECREF(msg);
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
+
+static int
+compiler_call(struct compiler *c, expr_ty e)
+{
+ int ret = maybe_optimize_method_call(c, e);
+ if (ret >= 0) {
+ return ret;
+ }
+ if (!check_caller(c, e->v.Call.func)) {
+ return 0;
+ }
+ VISIT(c, expr, e->v.Call.func);
+ return compiler_call_helper(c, 0,
+ e->v.Call.args,
+ e->v.Call.keywords);
+}
+
+static int
+compiler_joined_str(struct compiler *c, expr_ty e)
+{
+ VISIT_SEQ(c, expr, e->v.JoinedStr.values);
+ if (asdl_seq_LEN(e->v.JoinedStr.values) != 1)
+ ADDOP_I(c, BUILD_STRING, asdl_seq_LEN(e->v.JoinedStr.values));
+ return 1;
+}
+
+/* Used to implement f-strings. Format a single value. */
+static int
+compiler_formatted_value(struct compiler *c, expr_ty e)
+{
+ /* Our oparg encodes 2 pieces of information: the conversion
+ character, and whether or not a format_spec was provided.
+
+ Convert the conversion char to 3 bits:
+ : 000 0x0 FVC_NONE The default if nothing specified.
+ !s : 001 0x1 FVC_STR
+ !r : 010 0x2 FVC_REPR
+ !a : 011 0x3 FVC_ASCII
+
+ next bit is whether or not we have a format spec:
+ yes : 100 0x4
+ no : 000 0x0
+ */
+
+ int conversion = e->v.FormattedValue.conversion;
+ int oparg;
+
+ /* The expression to be formatted. */
+ VISIT(c, expr, e->v.FormattedValue.value);
+
+ switch (conversion) {
+ case 's': oparg = FVC_STR; break;
+ case 'r': oparg = FVC_REPR; break;
+ case 'a': oparg = FVC_ASCII; break;
+ case -1: oparg = FVC_NONE; break;
+ default:
+ PyErr_Format(PyExc_SystemError,
+ "Unrecognized conversion character %d", conversion);
+ return 0;
+ }
+ if (e->v.FormattedValue.format_spec) {
+ /* Evaluate the format spec, and update our opcode arg. */
+ VISIT(c, expr, e->v.FormattedValue.format_spec);
+ oparg |= FVS_HAVE_SPEC;
+ }
+
+ /* And push our opcode and oparg */
+ ADDOP_I(c, FORMAT_VALUE, oparg);
+
+ return 1;
+}
+
+static int
+compiler_subkwargs(struct compiler *c, asdl_seq *keywords, Py_ssize_t begin, Py_ssize_t end)
+{
+ Py_ssize_t i, n = end - begin;
+ keyword_ty kw;
+ PyObject *keys, *key;
+ assert(n > 0);
+ if (n > 1) {
+ for (i = begin; i < end; i++) {
+ kw = asdl_seq_GET(keywords, i);
+ VISIT(c, expr, kw->value);
+ }
+ keys = PyTuple_New(n);
+ if (keys == NULL) {
+ return 0;
+ }
+ for (i = begin; i < end; i++) {
+ key = ((keyword_ty) asdl_seq_GET(keywords, i))->arg;
+ Py_INCREF(key);
+ PyTuple_SET_ITEM(keys, i - begin, key);
+ }
+ ADDOP_LOAD_CONST_NEW(c, keys);
+ ADDOP_I(c, BUILD_CONST_KEY_MAP, n);
+ }
+ else {
+ /* a for loop only executes once */
+ for (i = begin; i < end; i++) {
+ kw = asdl_seq_GET(keywords, i);
+ ADDOP_LOAD_CONST(c, kw->arg);
+ VISIT(c, expr, kw->value);
+ }
+ ADDOP_I(c, BUILD_MAP, n);
+ }
+ return 1;
+}
+
+/* shared code between compiler_call and compiler_class */
+static int
+compiler_call_helper(struct compiler *c,
+ int n, /* Args already pushed */
+ asdl_seq *args,
+ asdl_seq *keywords)
+{
+ Py_ssize_t i, nseen, nelts, nkwelts;
+
+ if (validate_keywords(c, keywords) == -1) {
+ return 0;
+ }
+
+ nelts = asdl_seq_LEN(args);
+ nkwelts = asdl_seq_LEN(keywords);
+
+ for (i = 0; i < nelts; i++) {
+ expr_ty elt = asdl_seq_GET(args, i);
+ if (elt->kind == Starred_kind) {
+ goto ex_call;
+ }
+ }
+ for (i = 0; i < nkwelts; i++) {
+ keyword_ty kw = asdl_seq_GET(keywords, i);
+ if (kw->arg == NULL) {
+ goto ex_call;
+ }
+ }
+
+ /* No * or ** args, so can use faster calling sequence */
+ for (i = 0; i < nelts; i++) {
+ expr_ty elt = asdl_seq_GET(args, i);
+ assert(elt->kind != Starred_kind);
+ VISIT(c, expr, elt);
+ }
+ if (nkwelts) {
+ PyObject *names;
+ VISIT_SEQ(c, keyword, keywords);
+ names = PyTuple_New(nkwelts);
+ if (names == NULL) {
+ return 0;
+ }
+ for (i = 0; i < nkwelts; i++) {
+ keyword_ty kw = asdl_seq_GET(keywords, i);
+ Py_INCREF(kw->arg);
+ PyTuple_SET_ITEM(names, i, kw->arg);
+ }
+ ADDOP_LOAD_CONST_NEW(c, names);
+ ADDOP_I(c, CALL_FUNCTION_KW, n + nelts + nkwelts);
+ return 1;
+ }
+ else {
+ ADDOP_I(c, CALL_FUNCTION, n + nelts);
+ return 1;
+ }
+
+ex_call:
+
+ /* Do positional arguments. */
+ if (n ==0 && nelts == 1 && ((expr_ty)asdl_seq_GET(args, 0))->kind == Starred_kind) {
+ VISIT(c, expr, ((expr_ty)asdl_seq_GET(args, 0))->v.Starred.value);
+ }
+ else if (starunpack_helper(c, args, n, BUILD_LIST,
+ LIST_APPEND, LIST_EXTEND, 1) == 0) {
+ return 0;
+ }
+ /* Then keyword arguments */
+ if (nkwelts) {
+ /* Has a new dict been pushed */
+ int have_dict = 0;
+
+ nseen = 0; /* the number of keyword arguments on the stack following */
+ for (i = 0; i < nkwelts; i++) {
+ keyword_ty kw = asdl_seq_GET(keywords, i);
+ if (kw->arg == NULL) {
+ /* A keyword argument unpacking. */
+ if (nseen) {
+ if (!compiler_subkwargs(c, keywords, i - nseen, i)) {
+ return 0;
+ }
+ if (have_dict) {
+ ADDOP_I(c, DICT_MERGE, 1);
+ }
+ have_dict = 1;
+ nseen = 0;
+ }
+ if (!have_dict) {
+ ADDOP_I(c, BUILD_MAP, 0);
+ have_dict = 1;
+ }
+ VISIT(c, expr, kw->value);
+ ADDOP_I(c, DICT_MERGE, 1);
+ }
+ else {
+ nseen++;
+ }
+ }
+ if (nseen) {
+ /* Pack up any trailing keyword arguments. */
+ if (!compiler_subkwargs(c, keywords, nkwelts - nseen, nkwelts)) {
+ return 0;
+ }
+ if (have_dict) {
+ ADDOP_I(c, DICT_MERGE, 1);
+ }
+ have_dict = 1;
+ }
+ assert(have_dict);
+ }
+ ADDOP_I(c, CALL_FUNCTION_EX, nkwelts > 0);
+ return 1;
+}
+
+
+/* List and set comprehensions and generator expressions work by creating a
+ nested function to perform the actual iteration. This means that the
+ iteration variables don't leak into the current scope.
+ The defined function is called immediately following its definition, with the
+ result of that call being the result of the expression.
+ The LC/SC version returns the populated container, while the GE version is
+ flagged in symtable.c as a generator, so it returns the generator object
+ when the function is called.
+
+ Possible cleanups:
+ - iterate over the generator sequence instead of using recursion
+*/
+
+
+static int
+compiler_comprehension_generator(struct compiler *c,
+ asdl_seq *generators, int gen_index,
+ int depth,
+ expr_ty elt, expr_ty val, int type)
+{
+ comprehension_ty gen;
+ gen = (comprehension_ty)asdl_seq_GET(generators, gen_index);
+ if (gen->is_async) {
+ return compiler_async_comprehension_generator(
+ c, generators, gen_index, depth, elt, val, type);
+ } else {
+ return compiler_sync_comprehension_generator(
+ c, generators, gen_index, depth, elt, val, type);
+ }
+}
+
+static int
+compiler_sync_comprehension_generator(struct compiler *c,
+ asdl_seq *generators, int gen_index,
+ int depth,
+ expr_ty elt, expr_ty val, int type)
+{
+ /* generate code for the iterator, then each of the ifs,
+ and then write to the element */
+
+ comprehension_ty gen;
+ basicblock *start, *anchor, *skip, *if_cleanup;
+ Py_ssize_t i, n;
+
+ start = compiler_new_block(c);
+ skip = compiler_new_block(c);
+ if_cleanup = compiler_new_block(c);
+ anchor = compiler_new_block(c);
+
+ if (start == NULL || skip == NULL || if_cleanup == NULL ||
+ anchor == NULL)
+ return 0;
+
+ gen = (comprehension_ty)asdl_seq_GET(generators, gen_index);
+
+ if (gen_index == 0) {
+ /* Receive outermost iter as an implicit argument */
+ c->u->u_argcount = 1;
+ ADDOP_I(c, LOAD_FAST, 0);
+ }
+ else {
+ /* Sub-iter - calculate on the fly */
+ /* Fast path for the temporary variable assignment idiom:
+ for y in [f(x)]
+ */
+ asdl_seq *elts;
+ switch (gen->iter->kind) {
+ case List_kind:
+ elts = gen->iter->v.List.elts;
+ break;
+ case Tuple_kind:
+ elts = gen->iter->v.Tuple.elts;
+ break;
+ default:
+ elts = NULL;
+ }
+ if (asdl_seq_LEN(elts) == 1) {
+ expr_ty elt = asdl_seq_GET(elts, 0);
+ if (elt->kind != Starred_kind) {
+ VISIT(c, expr, elt);
+ start = NULL;
+ }
+ }
+ if (start) {
+ VISIT(c, expr, gen->iter);
+ ADDOP(c, GET_ITER);
+ }
+ }
+ if (start) {
+ depth++;
+ compiler_use_next_block(c, start);
+ ADDOP_JREL(c, FOR_ITER, anchor);
+ NEXT_BLOCK(c);
+ }
+ VISIT(c, expr, gen->target);
+
+ /* XXX this needs to be cleaned up...a lot! */
+ n = asdl_seq_LEN(gen->ifs);
+ for (i = 0; i < n; i++) {
+ expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i);
+ if (!compiler_jump_if(c, e, if_cleanup, 0))
+ return 0;
+ NEXT_BLOCK(c);
+ }
+
+ if (++gen_index < asdl_seq_LEN(generators))
+ if (!compiler_comprehension_generator(c,
+ generators, gen_index, depth,
+ elt, val, type))
+ return 0;
+
+ /* only append after the last for generator */
+ if (gen_index >= asdl_seq_LEN(generators)) {
+ /* comprehension specific code */
+ switch (type) {
+ case COMP_GENEXP:
+ VISIT(c, expr, elt);
+ ADDOP(c, YIELD_VALUE);
+ ADDOP(c, POP_TOP);
+ break;
+ case COMP_LISTCOMP:
+ VISIT(c, expr, elt);
+ ADDOP_I(c, LIST_APPEND, depth + 1);
+ break;
+ case COMP_SETCOMP:
+ VISIT(c, expr, elt);
+ ADDOP_I(c, SET_ADD, depth + 1);
+ break;
+ case COMP_DICTCOMP:
+ /* With '{k: v}', k is evaluated before v, so we do
+ the same. */
+ VISIT(c, expr, elt);
+ VISIT(c, expr, val);
+ ADDOP_I(c, MAP_ADD, depth + 1);
+ break;
+ default:
+ return 0;
+ }
+
+ compiler_use_next_block(c, skip);
+ }
+ compiler_use_next_block(c, if_cleanup);
+ if (start) {
+ ADDOP_JABS(c, JUMP_ABSOLUTE, start);
+ compiler_use_next_block(c, anchor);
+ }
+
+ return 1;
+}
+
+static int
+compiler_async_comprehension_generator(struct compiler *c,
+ asdl_seq *generators, int gen_index,
+ int depth,
+ expr_ty elt, expr_ty val, int type)
+{
+ comprehension_ty gen;
+ basicblock *start, *if_cleanup, *except;
+ Py_ssize_t i, n;
+ start = compiler_new_block(c);
+ except = compiler_new_block(c);
+ if_cleanup = compiler_new_block(c);
+
+ if (start == NULL || if_cleanup == NULL || except == NULL) {
+ return 0;
+ }
+
+ gen = (comprehension_ty)asdl_seq_GET(generators, gen_index);
+
+ if (gen_index == 0) {
+ /* Receive outermost iter as an implicit argument */
+ c->u->u_argcount = 1;
+ ADDOP_I(c, LOAD_FAST, 0);
+ }
+ else {
+ /* Sub-iter - calculate on the fly */
+ VISIT(c, expr, gen->iter);
+ ADDOP(c, GET_AITER);
+ }
+
+ compiler_use_next_block(c, start);
+
+ ADDOP_JREL(c, SETUP_FINALLY, except);
+ ADDOP(c, GET_ANEXT);
+ ADDOP_LOAD_CONST(c, Py_None);
+ ADDOP(c, YIELD_FROM);
+ ADDOP(c, POP_BLOCK);
+ VISIT(c, expr, gen->target);
+
+ n = asdl_seq_LEN(gen->ifs);
+ for (i = 0; i < n; i++) {
+ expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i);
+ if (!compiler_jump_if(c, e, if_cleanup, 0))
+ return 0;
+ NEXT_BLOCK(c);
+ }
+
+ depth++;
+ if (++gen_index < asdl_seq_LEN(generators))
+ if (!compiler_comprehension_generator(c,
+ generators, gen_index, depth,
+ elt, val, type))
+ return 0;
+
+ /* only append after the last for generator */
+ if (gen_index >= asdl_seq_LEN(generators)) {
+ /* comprehension specific code */
+ switch (type) {
+ case COMP_GENEXP:
+ VISIT(c, expr, elt);
+ ADDOP(c, YIELD_VALUE);
+ ADDOP(c, POP_TOP);
+ break;
+ case COMP_LISTCOMP:
+ VISIT(c, expr, elt);
+ ADDOP_I(c, LIST_APPEND, depth + 1);
+ break;
+ case COMP_SETCOMP:
+ VISIT(c, expr, elt);
+ ADDOP_I(c, SET_ADD, depth + 1);
+ break;
+ case COMP_DICTCOMP:
+ /* With '{k: v}', k is evaluated before v, so we do
+ the same. */
+ VISIT(c, expr, elt);
+ VISIT(c, expr, val);
+ ADDOP_I(c, MAP_ADD, depth + 1);
+ break;
+ default:
+ return 0;
+ }
+ }
+ compiler_use_next_block(c, if_cleanup);
+ ADDOP_JABS(c, JUMP_ABSOLUTE, start);
+
+ compiler_use_next_block(c, except);
+ ADDOP(c, END_ASYNC_FOR);
+
+ return 1;
+}
+
+static int
+compiler_comprehension(struct compiler *c, expr_ty e, int type,
+ identifier name, asdl_seq *generators, expr_ty elt,
+ expr_ty val)
+{
+ PyCodeObject *co = NULL;
+ comprehension_ty outermost;
+ PyObject *qualname = NULL;
+ int is_async_generator = 0;
+ int top_level_await = IS_TOP_LEVEL_AWAIT(c);
+
+
+ int is_async_function = c->u->u_ste->ste_coroutine;
+
+ outermost = (comprehension_ty) asdl_seq_GET(generators, 0);
+ if (!compiler_enter_scope(c, name, COMPILER_SCOPE_COMPREHENSION,
+ (void *)e, e->lineno))
+ {
+ goto error;
+ }
+
+ is_async_generator = c->u->u_ste->ste_coroutine;
+
+ if (is_async_generator && !is_async_function && type != COMP_GENEXP && !top_level_await) {
+ compiler_error(c, "asynchronous comprehension outside of "
+ "an asynchronous function");
+ goto error_in_scope;
+ }
+
+ if (type != COMP_GENEXP) {
+ int op;
+ switch (type) {
+ case COMP_LISTCOMP:
+ op = BUILD_LIST;
+ break;
+ case COMP_SETCOMP:
+ op = BUILD_SET;
+ break;
+ case COMP_DICTCOMP:
+ op = BUILD_MAP;
+ break;
+ default:
+ PyErr_Format(PyExc_SystemError,
+ "unknown comprehension type %d", type);
+ goto error_in_scope;
+ }
+
+ ADDOP_I(c, op, 0);
+ }
+
+ if (!compiler_comprehension_generator(c, generators, 0, 0, elt,
+ val, type))
+ goto error_in_scope;
+
+ if (type != COMP_GENEXP) {
+ ADDOP(c, RETURN_VALUE);
+ }
+
+ co = assemble(c, 1);
+ qualname = c->u->u_qualname;
+ Py_INCREF(qualname);
+ compiler_exit_scope(c);
+ if (top_level_await && is_async_generator){
+ c->u->u_ste->ste_coroutine = 1;
+ }
+ if (co == NULL)
+ goto error;
+
+ if (!compiler_make_closure(c, co, 0, qualname))
+ goto error;
+ Py_DECREF(qualname);
+ Py_DECREF(co);
+
+ VISIT(c, expr, outermost->iter);
+
+ if (outermost->is_async) {
+ ADDOP(c, GET_AITER);
+ } else {
+ ADDOP(c, GET_ITER);
+ }
+
+ ADDOP_I(c, CALL_FUNCTION, 1);
+
+ if (is_async_generator && type != COMP_GENEXP) {
+ ADDOP(c, GET_AWAITABLE);
+ ADDOP_LOAD_CONST(c, Py_None);
+ ADDOP(c, YIELD_FROM);
+ }
+
+ return 1;
+error_in_scope:
+ compiler_exit_scope(c);
+error:
+ Py_XDECREF(qualname);
+ Py_XDECREF(co);
+ return 0;
+}
+
+static int
+compiler_genexp(struct compiler *c, expr_ty e)
+{
+ static identifier name;
+ if (!name) {
+ name = PyUnicode_InternFromString("<genexpr>");
+ if (!name)
+ return 0;
+ }
+ assert(e->kind == GeneratorExp_kind);
+ return compiler_comprehension(c, e, COMP_GENEXP, name,
+ e->v.GeneratorExp.generators,
+ e->v.GeneratorExp.elt, NULL);
+}
+
+static int
+compiler_listcomp(struct compiler *c, expr_ty e)
+{
+ static identifier name;
+ if (!name) {
+ name = PyUnicode_InternFromString("<listcomp>");
+ if (!name)
+ return 0;
+ }
+ assert(e->kind == ListComp_kind);
+ return compiler_comprehension(c, e, COMP_LISTCOMP, name,
+ e->v.ListComp.generators,
+ e->v.ListComp.elt, NULL);
+}
+
+static int
+compiler_setcomp(struct compiler *c, expr_ty e)
+{
+ static identifier name;
+ if (!name) {
+ name = PyUnicode_InternFromString("<setcomp>");
+ if (!name)
+ return 0;
+ }
+ assert(e->kind == SetComp_kind);
+ return compiler_comprehension(c, e, COMP_SETCOMP, name,
+ e->v.SetComp.generators,
+ e->v.SetComp.elt, NULL);
+}
+
+
+static int
+compiler_dictcomp(struct compiler *c, expr_ty e)
+{
+ static identifier name;
+ if (!name) {
+ name = PyUnicode_InternFromString("<dictcomp>");
+ if (!name)
+ return 0;
+ }
+ assert(e->kind == DictComp_kind);
+ return compiler_comprehension(c, e, COMP_DICTCOMP, name,
+ e->v.DictComp.generators,
+ e->v.DictComp.key, e->v.DictComp.value);
+}
+
+
+static int
+compiler_visit_keyword(struct compiler *c, keyword_ty k)
+{
+ VISIT(c, expr, k->value);
+ return 1;
+}
+
+/* Test whether expression is constant. For constants, report
+ whether they are true or false.
+
+ Return values: 1 for true, 0 for false, -1 for non-constant.
+ */
+
+static int
+expr_constant(expr_ty e)
+{
+ if (e->kind == Constant_kind) {
+ return PyObject_IsTrue(e->v.Constant.value);
+ }
+ return -1;
+}
+
+static int
+compiler_with_except_finish(struct compiler *c) {
+ basicblock *exit;
+ exit = compiler_new_block(c);
+ if (exit == NULL)
+ return 0;
+ ADDOP_JABS(c, POP_JUMP_IF_TRUE, exit);
+ ADDOP(c, RERAISE);
+ compiler_use_next_block(c, exit);
+ ADDOP(c, POP_TOP);
+ ADDOP(c, POP_TOP);
+ ADDOP(c, POP_TOP);
+ ADDOP(c, POP_EXCEPT);
+ ADDOP(c, POP_TOP);
+ return 1;
+}
+
+/*
+ Implements the async with statement.
+
+ The semantics outlined in that PEP are as follows:
+
+ async with EXPR as VAR:
+ BLOCK
+
+ It is implemented roughly as:
+
+ context = EXPR
+ exit = context.__aexit__ # not calling it
+ value = await context.__aenter__()
+ try:
+ VAR = value # if VAR present in the syntax
+ BLOCK
+ finally:
+ if an exception was raised:
+ exc = copy of (exception, instance, traceback)
+ else:
+ exc = (None, None, None)
+ if not (await exit(*exc)):
+ raise
+ */
+static int
+compiler_async_with(struct compiler *c, stmt_ty s, int pos)
+{
+ basicblock *block, *final, *exit;
+ withitem_ty item = asdl_seq_GET(s->v.AsyncWith.items, pos);
+
+ assert(s->kind == AsyncWith_kind);
+ if (IS_TOP_LEVEL_AWAIT(c)){
+ c->u->u_ste->ste_coroutine = 1;
+ } else if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION){
+ return compiler_error(c, "'async with' outside async function");
+ }
+
+ block = compiler_new_block(c);
+ final = compiler_new_block(c);
+ exit = compiler_new_block(c);
+ if (!block || !final || !exit)
+ return 0;
+
+ /* Evaluate EXPR */
+ VISIT(c, expr, item->context_expr);
+
+ ADDOP(c, BEFORE_ASYNC_WITH);
+ ADDOP(c, GET_AWAITABLE);
+ ADDOP_LOAD_CONST(c, Py_None);
+ ADDOP(c, YIELD_FROM);
+
+ ADDOP_JREL(c, SETUP_ASYNC_WITH, final);
+
+ /* SETUP_ASYNC_WITH pushes a finally block. */
+ compiler_use_next_block(c, block);
+ if (!compiler_push_fblock(c, ASYNC_WITH, block, final, NULL)) {
+ return 0;
+ }
+
+ if (item->optional_vars) {
+ VISIT(c, expr, item->optional_vars);
+ }
+ else {
+ /* Discard result from context.__aenter__() */
+ ADDOP(c, POP_TOP);
+ }
+
+ pos++;
+ if (pos == asdl_seq_LEN(s->v.AsyncWith.items))
+ /* BLOCK code */
+ VISIT_SEQ(c, stmt, s->v.AsyncWith.body)
+ else if (!compiler_async_with(c, s, pos))
+ return 0;
+
+ compiler_pop_fblock(c, ASYNC_WITH, block);
+ ADDOP(c, POP_BLOCK);
+ /* End of body; start the cleanup */
+
+ /* For successful outcome:
+ * call __exit__(None, None, None)
+ */
+ if(!compiler_call_exit_with_nones(c))
+ return 0;
+ ADDOP(c, GET_AWAITABLE);
+ ADDOP_O(c, LOAD_CONST, Py_None, consts);
+ ADDOP(c, YIELD_FROM);
+
+ ADDOP(c, POP_TOP);
+
+ ADDOP_JABS(c, JUMP_ABSOLUTE, exit);
+
+ /* For exceptional outcome: */
+ compiler_use_next_block(c, final);
+
+ ADDOP(c, WITH_EXCEPT_START);
+ ADDOP(c, GET_AWAITABLE);
+ ADDOP_LOAD_CONST(c, Py_None);
+ ADDOP(c, YIELD_FROM);
+ compiler_with_except_finish(c);
+
+compiler_use_next_block(c, exit);
+ return 1;
+}
+
+
+/*
+ Implements the with statement from PEP 343.
+ with EXPR as VAR:
+ BLOCK
+ is implemented as:
+ <code for EXPR>
+ SETUP_WITH E
+ <code to store to VAR> or POP_TOP
+ <code for BLOCK>
+ LOAD_CONST (None, None, None)
+ CALL_FUNCTION_EX 0
+ JUMP_FORWARD EXIT
+ E: WITH_EXCEPT_START (calls EXPR.__exit__)
+ POP_JUMP_IF_TRUE T:
+ RERAISE
+ T: POP_TOP * 3 (remove exception from stack)
+ POP_EXCEPT
+ POP_TOP
+ EXIT:
+ */
+
+static int
+compiler_with(struct compiler *c, stmt_ty s, int pos)
+{
+ basicblock *block, *final, *exit;
+ withitem_ty item = asdl_seq_GET(s->v.With.items, pos);
+
+ assert(s->kind == With_kind);
+
+ block = compiler_new_block(c);
+ final = compiler_new_block(c);
+ exit = compiler_new_block(c);
+ if (!block || !final || !exit)
+ return 0;
+
+ /* Evaluate EXPR */
+ VISIT(c, expr, item->context_expr);
+ /* Will push bound __exit__ */
+ ADDOP_JREL(c, SETUP_WITH, final);
+
+ /* SETUP_WITH pushes a finally block. */
+ compiler_use_next_block(c, block);
+ if (!compiler_push_fblock(c, WITH, block, final, NULL)) {
+ return 0;
+ }
+
+ if (item->optional_vars) {
+ VISIT(c, expr, item->optional_vars);
+ }
+ else {
+ /* Discard result from context.__enter__() */
+ ADDOP(c, POP_TOP);
+ }
+
+ pos++;
+ if (pos == asdl_seq_LEN(s->v.With.items))
+ /* BLOCK code */
+ VISIT_SEQ(c, stmt, s->v.With.body)
+ else if (!compiler_with(c, s, pos))
+ return 0;
+
+ ADDOP(c, POP_BLOCK);
+ compiler_pop_fblock(c, WITH, block);
+
+ /* End of body; start the cleanup. */
+
+ /* For successful outcome:
+ * call __exit__(None, None, None)
+ */
+ if (!compiler_call_exit_with_nones(c))
+ return 0;
+ ADDOP(c, POP_TOP);
+ ADDOP_JREL(c, JUMP_FORWARD, exit);
+
+ /* For exceptional outcome: */
+ compiler_use_next_block(c, final);
+
+ ADDOP(c, WITH_EXCEPT_START);
+ compiler_with_except_finish(c);
+
+ compiler_use_next_block(c, exit);
+ return 1;
+}
+
+static int
+compiler_visit_expr1(struct compiler *c, expr_ty e)
+{
+ switch (e->kind) {
+ case NamedExpr_kind:
+ VISIT(c, expr, e->v.NamedExpr.value);
+ ADDOP(c, DUP_TOP);
+ VISIT(c, expr, e->v.NamedExpr.target);
+ break;
+ case BoolOp_kind:
+ return compiler_boolop(c, e);
+ case BinOp_kind:
+ VISIT(c, expr, e->v.BinOp.left);
+ VISIT(c, expr, e->v.BinOp.right);
+ ADDOP(c, binop(e->v.BinOp.op));
+ break;
+ case UnaryOp_kind:
+ VISIT(c, expr, e->v.UnaryOp.operand);
+ ADDOP(c, unaryop(e->v.UnaryOp.op));
+ break;
+ case Lambda_kind:
+ return compiler_lambda(c, e);
+ case IfExp_kind:
+ return compiler_ifexp(c, e);
+ case Dict_kind:
+ return compiler_dict(c, e);
+ case Set_kind:
+ return compiler_set(c, e);
+ case GeneratorExp_kind:
+ return compiler_genexp(c, e);
+ case ListComp_kind:
+ return compiler_listcomp(c, e);
+ case SetComp_kind:
+ return compiler_setcomp(c, e);
+ case DictComp_kind:
+ return compiler_dictcomp(c, e);
+ case Yield_kind:
+ if (c->u->u_ste->ste_type != FunctionBlock)
+ return compiler_error(c, "'yield' outside function");
+ if (e->v.Yield.value) {
+ VISIT(c, expr, e->v.Yield.value);
+ }
+ else {
+ ADDOP_LOAD_CONST(c, Py_None);
+ }
+ ADDOP(c, YIELD_VALUE);
+ break;
+ case YieldFrom_kind:
+ if (c->u->u_ste->ste_type != FunctionBlock)
+ return compiler_error(c, "'yield' outside function");
+
+ if (c->u->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION)
+ return compiler_error(c, "'yield from' inside async function");
+
+ VISIT(c, expr, e->v.YieldFrom.value);
+ ADDOP(c, GET_YIELD_FROM_ITER);
+ ADDOP_LOAD_CONST(c, Py_None);
+ ADDOP(c, YIELD_FROM);
+ break;
+ case Await_kind:
+ if (!IS_TOP_LEVEL_AWAIT(c)){
+ if (c->u->u_ste->ste_type != FunctionBlock){
+ return compiler_error(c, "'await' outside function");
+ }
+
+ if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION &&
+ c->u->u_scope_type != COMPILER_SCOPE_COMPREHENSION){
+ return compiler_error(c, "'await' outside async function");
+ }
+ }
+
+ VISIT(c, expr, e->v.Await.value);
+ ADDOP(c, GET_AWAITABLE);
+ ADDOP_LOAD_CONST(c, Py_None);
+ ADDOP(c, YIELD_FROM);
+ break;
+ case Compare_kind:
+ return compiler_compare(c, e);
+ case Call_kind:
+ return compiler_call(c, e);
+ case Constant_kind:
+ ADDOP_LOAD_CONST(c, e->v.Constant.value);
+ break;
+ case JoinedStr_kind:
+ return compiler_joined_str(c, e);
+ case FormattedValue_kind:
+ return compiler_formatted_value(c, e);
+ /* The following exprs can be assignment targets. */
+ case Attribute_kind:
+ VISIT(c, expr, e->v.Attribute.value);
+ switch (e->v.Attribute.ctx) {
+ case Load:
+ ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names);
+ break;
+ case Store:
+ if (forbidden_name(c, e->v.Attribute.attr, e->v.Attribute.ctx))
+ return 0;
+ ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names);
+ break;
+ case Del:
+ ADDOP_NAME(c, DELETE_ATTR, e->v.Attribute.attr, names);
+ break;
+ }
+ break;
+ case Subscript_kind:
+ return compiler_subscript(c, e);
+ case Starred_kind:
+ switch (e->v.Starred.ctx) {
+ case Store:
+ /* In all legitimate cases, the Starred node was already replaced
+ * by compiler_list/compiler_tuple. XXX: is that okay? */
+ return compiler_error(c,
+ "starred assignment target must be in a list or tuple");
+ default:
+ return compiler_error(c,
+ "can't use starred expression here");
+ }
+ break;
+ case Slice_kind:
+ return compiler_slice(c, e);
+ case Name_kind:
+ return compiler_nameop(c, e->v.Name.id, e->v.Name.ctx);
+ /* child nodes of List and Tuple will have expr_context set */
+ case List_kind:
+ return compiler_list(c, e);
+ case Tuple_kind:
+ return compiler_tuple(c, e);
+ }
+ return 1;
+}
+
+static int
+compiler_visit_expr(struct compiler *c, expr_ty e)
+{
+ int old_lineno = c->u->u_lineno;
+ int old_col_offset = c->u->u_col_offset;
+ SET_LOC(c, e);
+ int res = compiler_visit_expr1(c, e);
+ c->u->u_lineno = old_lineno;
+ c->u->u_col_offset = old_col_offset;
+ return res;
+}
+
+static int
+compiler_augassign(struct compiler *c, stmt_ty s)
+{
+ assert(s->kind == AugAssign_kind);
+ expr_ty e = s->v.AugAssign.target;
+
+ int old_lineno = c->u->u_lineno;
+ int old_col_offset = c->u->u_col_offset;
+ SET_LOC(c, e);
+
+ switch (e->kind) {
+ case Attribute_kind:
+ VISIT(c, expr, e->v.Attribute.value);
+ ADDOP(c, DUP_TOP);
+ ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names);
+ break;
+ case Subscript_kind:
+ VISIT(c, expr, e->v.Subscript.value);
+ VISIT(c, expr, e->v.Subscript.slice);
+ ADDOP(c, DUP_TOP_TWO);
+ ADDOP(c, BINARY_SUBSCR);
+ break;
+ case Name_kind:
+ if (!compiler_nameop(c, e->v.Name.id, Load))
+ return 0;
+ break;
+ default:
+ PyErr_Format(PyExc_SystemError,
+ "invalid node type (%d) for augmented assignment",
+ e->kind);
+ return 0;
+ }
+
+ c->u->u_lineno = old_lineno;
+ c->u->u_col_offset = old_col_offset;
+
+ VISIT(c, expr, s->v.AugAssign.value);
+ ADDOP(c, inplace_binop(s->v.AugAssign.op));
+
+ SET_LOC(c, e);
+
+ switch (e->kind) {
+ case Attribute_kind:
+ ADDOP(c, ROT_TWO);
+ ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names);
+ break;
+ case Subscript_kind:
+ ADDOP(c, ROT_THREE);
+ ADDOP(c, STORE_SUBSCR);
+ break;
+ case Name_kind:
+ return compiler_nameop(c, e->v.Name.id, Store);
+ default:
+ Py_UNREACHABLE();
+ }
+ return 1;
+}
+
+static int
+check_ann_expr(struct compiler *c, expr_ty e)
+{
+ VISIT(c, expr, e);
+ ADDOP(c, POP_TOP);
+ return 1;
+}
+
+static int
+check_annotation(struct compiler *c, stmt_ty s)
+{
+ /* Annotations are only evaluated in a module or class. */
+ if (c->u->u_scope_type == COMPILER_SCOPE_MODULE ||
+ c->u->u_scope_type == COMPILER_SCOPE_CLASS) {
+ return check_ann_expr(c, s->v.AnnAssign.annotation);
+ }
+ return 1;
+}
+
+static int
+check_ann_subscr(struct compiler *c, expr_ty e)
+{
+ /* We check that everything in a subscript is defined at runtime. */
+ switch (e->kind) {
+ case Slice_kind:
+ if (e->v.Slice.lower && !check_ann_expr(c, e->v.Slice.lower)) {
+ return 0;
+ }
+ if (e->v.Slice.upper && !check_ann_expr(c, e->v.Slice.upper)) {
+ return 0;
+ }
+ if (e->v.Slice.step && !check_ann_expr(c, e->v.Slice.step)) {
+ return 0;
+ }
+ return 1;
+ case Tuple_kind: {
+ /* extended slice */
+ asdl_seq *elts = e->v.Tuple.elts;
+ Py_ssize_t i, n = asdl_seq_LEN(elts);
+ for (i = 0; i < n; i++) {
+ if (!check_ann_subscr(c, asdl_seq_GET(elts, i))) {
+ return 0;
+ }
+ }
+ return 1;
+ }
+ default:
+ return check_ann_expr(c, e);
+ }
+}
+
+static int
+compiler_annassign(struct compiler *c, stmt_ty s)
+{
+ expr_ty targ = s->v.AnnAssign.target;
+ PyObject* mangled;
+
+ assert(s->kind == AnnAssign_kind);
+
+ /* We perform the actual assignment first. */
+ if (s->v.AnnAssign.value) {
+ VISIT(c, expr, s->v.AnnAssign.value);
+ VISIT(c, expr, targ);
+ }
+ switch (targ->kind) {
+ case Name_kind:
+ if (forbidden_name(c, targ->v.Name.id, Store))
+ return 0;
+ /* If we have a simple name in a module or class, store annotation. */
+ if (s->v.AnnAssign.simple &&
+ (c->u->u_scope_type == COMPILER_SCOPE_MODULE ||
+ c->u->u_scope_type == COMPILER_SCOPE_CLASS)) {
+ if (c->c_future->ff_features & CO_FUTURE_ANNOTATIONS) {
+ VISIT(c, annexpr, s->v.AnnAssign.annotation)
+ }
+ else {
+ VISIT(c, expr, s->v.AnnAssign.annotation);
+ }
+ ADDOP_NAME(c, LOAD_NAME, __annotations__, names);
+ mangled = _Py_Mangle(c->u->u_private, targ->v.Name.id);
+ ADDOP_LOAD_CONST_NEW(c, mangled);
+ ADDOP(c, STORE_SUBSCR);
+ }
+ break;
+ case Attribute_kind:
+ if (forbidden_name(c, targ->v.Attribute.attr, Store))
+ return 0;
+ if (!s->v.AnnAssign.value &&
+ !check_ann_expr(c, targ->v.Attribute.value)) {
+ return 0;
+ }
+ break;
+ case Subscript_kind:
+ if (!s->v.AnnAssign.value &&
+ (!check_ann_expr(c, targ->v.Subscript.value) ||
+ !check_ann_subscr(c, targ->v.Subscript.slice))) {
+ return 0;
+ }
+ break;
+ default:
+ PyErr_Format(PyExc_SystemError,
+ "invalid node type (%d) for annotated assignment",
+ targ->kind);
+ return 0;
+ }
+ /* Annotation is evaluated last. */
+ if (!s->v.AnnAssign.simple && !check_annotation(c, s)) {
+ return 0;
+ }
+ return 1;
+}
+
+/* Raises a SyntaxError and returns 0.
+ If something goes wrong, a different exception may be raised.
+*/
+
+static int
+compiler_error(struct compiler *c, const char *errstr)
+{
+ PyObject *loc;
+ PyObject *u = NULL, *v = NULL;
+
+ loc = PyErr_ProgramTextObject(c->c_filename, c->u->u_lineno);
+ if (!loc) {
+ Py_INCREF(Py_None);
+ loc = Py_None;
+ }
+ u = Py_BuildValue("(OiiO)", c->c_filename, c->u->u_lineno,
+ c->u->u_col_offset + 1, loc);
+ if (!u)
+ goto exit;
+ v = Py_BuildValue("(zO)", errstr, u);
+ if (!v)
+ goto exit;
+ PyErr_SetObject(PyExc_SyntaxError, v);
+ exit:
+ Py_DECREF(loc);
+ Py_XDECREF(u);
+ Py_XDECREF(v);
+ return 0;
+}
+
+/* Emits a SyntaxWarning and returns 1 on success.
+ If a SyntaxWarning raised as error, replaces it with a SyntaxError
+ and returns 0.
+*/
+static int
+compiler_warn(struct compiler *c, const char *format, ...)
+{
+ va_list vargs;
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, format);
+#else
+ va_start(vargs);
+#endif
+ PyObject *msg = PyUnicode_FromFormatV(format, vargs);
+ va_end(vargs);
+ if (msg == NULL) {
+ return 0;
+ }
+ if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg, c->c_filename,
+ c->u->u_lineno, NULL, NULL) < 0)
+ {
+ if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) {
+ /* Replace the SyntaxWarning exception with a SyntaxError
+ to get a more accurate error report */
+ PyErr_Clear();
+ assert(PyUnicode_AsUTF8(msg) != NULL);
+ compiler_error(c, PyUnicode_AsUTF8(msg));
+ }
+ Py_DECREF(msg);
+ return 0;
+ }
+ Py_DECREF(msg);
+ return 1;
+}
+
+static int
+compiler_subscript(struct compiler *c, expr_ty e)
+{
+ expr_context_ty ctx = e->v.Subscript.ctx;
+ int op = 0;
+
+ if (ctx == Load) {
+ if (!check_subscripter(c, e->v.Subscript.value)) {
+ return 0;
+ }
+ if (!check_index(c, e->v.Subscript.value, e->v.Subscript.slice)) {
+ return 0;
+ }
+ }
+
+ switch (ctx) {
+ case Load: op = BINARY_SUBSCR; break;
+ case Store: op = STORE_SUBSCR; break;
+ case Del: op = DELETE_SUBSCR; break;
+ }
+ assert(op);
+ VISIT(c, expr, e->v.Subscript.value);
+ VISIT(c, expr, e->v.Subscript.slice);
+ ADDOP(c, op);
+ return 1;
+}
+
+static int
+compiler_slice(struct compiler *c, expr_ty s)
+{
+ int n = 2;
+ assert(s->kind == Slice_kind);
+
+ /* only handles the cases where BUILD_SLICE is emitted */
+ if (s->v.Slice.lower) {
+ VISIT(c, expr, s->v.Slice.lower);
+ }
+ else {
+ ADDOP_LOAD_CONST(c, Py_None);
+ }
+
+ if (s->v.Slice.upper) {
+ VISIT(c, expr, s->v.Slice.upper);
+ }
+ else {
+ ADDOP_LOAD_CONST(c, Py_None);
+ }
+
+ if (s->v.Slice.step) {
+ n++;
+ VISIT(c, expr, s->v.Slice.step);
+ }
+ ADDOP_I(c, BUILD_SLICE, n);
+ return 1;
+}
+
+/* End of the compiler section, beginning of the assembler section */
+
+/* do depth-first search of basic block graph, starting with block.
+ post records the block indices in post-order.
+
+ XXX must handle implicit jumps from one block to next
+*/
+
+struct assembler {
+ PyObject *a_bytecode; /* string containing bytecode */
+ int a_offset; /* offset into bytecode */
+ int a_nblocks; /* number of reachable blocks */
+ basicblock **a_postorder; /* list of blocks in dfs postorder */
+ PyObject *a_lnotab; /* string containing lnotab */
+ int a_lnotab_off; /* offset into lnotab */
+ int a_lineno; /* last lineno of emitted instruction */
+ int a_lineno_off; /* bytecode offset of last lineno */
+};
+
+static void
+dfs(struct compiler *c, basicblock *b, struct assembler *a, int end)
+{
+ int i, j;
+
+ /* Get rid of recursion for normal control flow.
+ Since the number of blocks is limited, unused space in a_postorder
+ (from a_nblocks to end) can be used as a stack for still not ordered
+ blocks. */
+ for (j = end; b && !b->b_seen; b = b->b_next) {
+ b->b_seen = 1;
+ assert(a->a_nblocks < j);
+ a->a_postorder[--j] = b;
+ }
+ while (j < end) {
+ b = a->a_postorder[j++];
+ for (i = 0; i < b->b_iused; i++) {
+ struct instr *instr = &b->b_instr[i];
+ if (instr->i_jrel || instr->i_jabs)
+ dfs(c, instr->i_target, a, j);
+ }
+ assert(a->a_nblocks < j);
+ a->a_postorder[a->a_nblocks++] = b;
+ }
+}
+
+Py_LOCAL_INLINE(void)
+stackdepth_push(basicblock ***sp, basicblock *b, int depth)
+{
+ assert(b->b_startdepth < 0 || b->b_startdepth == depth);
+ if (b->b_startdepth < depth && b->b_startdepth < 100) {
+ assert(b->b_startdepth < 0);
+ b->b_startdepth = depth;
+ *(*sp)++ = b;
+ }
+}
+
+/* Find the flow path that needs the largest stack. We assume that
+ * cycles in the flow graph have no net effect on the stack depth.
+ */
+static int
+stackdepth(struct compiler *c)
+{
+ basicblock *b, *entryblock = NULL;
+ basicblock **stack, **sp;
+ int nblocks = 0, maxdepth = 0;
+ for (b = c->u->u_blocks; b != NULL; b = b->b_list) {
+ b->b_startdepth = INT_MIN;
+ entryblock = b;
+ nblocks++;
+ }
+ if (!entryblock)
+ return 0;
+ stack = (basicblock **)PyObject_Malloc(sizeof(basicblock *) * nblocks);
+ if (!stack) {
+ PyErr_NoMemory();
+ return -1;
+ }
+
+ sp = stack;
+ stackdepth_push(&sp, entryblock, 0);
+ while (sp != stack) {
+ b = *--sp;
+ int depth = b->b_startdepth;
+ assert(depth >= 0);
+ basicblock *next = b->b_next;
+ for (int i = 0; i < b->b_iused; i++) {
+ struct instr *instr = &b->b_instr[i];
+ int effect = stack_effect(instr->i_opcode, instr->i_oparg, 0);
+ if (effect == PY_INVALID_STACK_EFFECT) {
+ _Py_FatalErrorFormat(__func__,
+ "opcode = %d", instr->i_opcode);
+ }
+ int new_depth = depth + effect;
+ if (new_depth > maxdepth) {
+ maxdepth = new_depth;
+ }
+ assert(depth >= 0); /* invalid code or bug in stackdepth() */
+ if (instr->i_jrel || instr->i_jabs) {
+ effect = stack_effect(instr->i_opcode, instr->i_oparg, 1);
+ assert(effect != PY_INVALID_STACK_EFFECT);
+ int target_depth = depth + effect;
+ if (target_depth > maxdepth) {
+ maxdepth = target_depth;
+ }
+ assert(target_depth >= 0); /* invalid code or bug in stackdepth() */
+ stackdepth_push(&sp, instr->i_target, target_depth);
+ }
+ depth = new_depth;
+ if (instr->i_opcode == JUMP_ABSOLUTE ||
+ instr->i_opcode == JUMP_FORWARD ||
+ instr->i_opcode == RETURN_VALUE ||
+ instr->i_opcode == RAISE_VARARGS ||
+ instr->i_opcode == RERAISE)
+ {
+ /* remaining code is dead */
+ next = NULL;
+ break;
+ }
+ }
+ if (next != NULL) {
+ stackdepth_push(&sp, next, depth);
+ }
+ }
+ PyObject_Free(stack);
+ return maxdepth;
+}
+
+static int
+assemble_init(struct assembler *a, int nblocks, int firstlineno)
+{
+ memset(a, 0, sizeof(struct assembler));
+ a->a_lineno = firstlineno;
+ a->a_bytecode = PyBytes_FromStringAndSize(NULL, DEFAULT_CODE_SIZE);
+ if (!a->a_bytecode)
+ return 0;
+ a->a_lnotab = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE);
+ if (!a->a_lnotab)
+ return 0;
+ if ((size_t)nblocks > SIZE_MAX / sizeof(basicblock *)) {
+ PyErr_NoMemory();
+ return 0;
+ }
+ a->a_postorder = (basicblock **)PyObject_Malloc(
+ sizeof(basicblock *) * nblocks);
+ if (!a->a_postorder) {
+ PyErr_NoMemory();
+ return 0;
+ }
+ return 1;
+}
+
+static void
+assemble_free(struct assembler *a)
+{
+ Py_XDECREF(a->a_bytecode);
+ Py_XDECREF(a->a_lnotab);
+ if (a->a_postorder)
+ PyObject_Free(a->a_postorder);
+}
+
+static int
+blocksize(basicblock *b)
+{
+ int i;
+ int size = 0;
+
+ for (i = 0; i < b->b_iused; i++)
+ size += instrsize(b->b_instr[i].i_oparg);
+ return size;
+}
+
+/* Appends a pair to the end of the line number table, a_lnotab, representing
+ the instruction's bytecode offset and line number. See
+ Objects/lnotab_notes.txt for the description of the line number table. */
+
+static int
+assemble_lnotab(struct assembler *a, struct instr *i)
+{
+ int d_bytecode, d_lineno;
+ Py_ssize_t len;
+ unsigned char *lnotab;
+
+ d_lineno = i->i_lineno - a->a_lineno;
+ if (d_lineno == 0) {
+ return 1;
+ }
+
+ d_bytecode = (a->a_offset - a->a_lineno_off) * sizeof(_Py_CODEUNIT);
+ assert(d_bytecode >= 0);
+
+ if (d_bytecode > 255) {
+ int j, nbytes, ncodes = d_bytecode / 255;
+ nbytes = a->a_lnotab_off + 2 * ncodes;
+ len = PyBytes_GET_SIZE(a->a_lnotab);
+ if (nbytes >= len) {
+ if ((len <= INT_MAX / 2) && (len * 2 < nbytes))
+ len = nbytes;
+ else if (len <= INT_MAX / 2)
+ len *= 2;
+ else {
+ PyErr_NoMemory();
+ return 0;
+ }
+ if (_PyBytes_Resize(&a->a_lnotab, len) < 0)
+ return 0;
+ }
+ lnotab = (unsigned char *)
+ PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
+ for (j = 0; j < ncodes; j++) {
+ *lnotab++ = 255;
+ *lnotab++ = 0;
+ }
+ d_bytecode -= ncodes * 255;
+ a->a_lnotab_off += ncodes * 2;
+ }
+ assert(0 <= d_bytecode && d_bytecode <= 255);
+
+ if (d_lineno < -128 || 127 < d_lineno) {
+ int j, nbytes, ncodes, k;
+ if (d_lineno < 0) {
+ k = -128;
+ /* use division on positive numbers */
+ ncodes = (-d_lineno) / 128;
+ }
+ else {
+ k = 127;
+ ncodes = d_lineno / 127;
+ }
+ d_lineno -= ncodes * k;
+ assert(ncodes >= 1);
+ nbytes = a->a_lnotab_off + 2 * ncodes;
+ len = PyBytes_GET_SIZE(a->a_lnotab);
+ if (nbytes >= len) {
+ if ((len <= INT_MAX / 2) && len * 2 < nbytes)
+ len = nbytes;
+ else if (len <= INT_MAX / 2)
+ len *= 2;
+ else {
+ PyErr_NoMemory();
+ return 0;
+ }
+ if (_PyBytes_Resize(&a->a_lnotab, len) < 0)
+ return 0;
+ }
+ lnotab = (unsigned char *)
+ PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
+ *lnotab++ = d_bytecode;
+ *lnotab++ = k;
+ d_bytecode = 0;
+ for (j = 1; j < ncodes; j++) {
+ *lnotab++ = 0;
+ *lnotab++ = k;
+ }
+ a->a_lnotab_off += ncodes * 2;
+ }
+ assert(-128 <= d_lineno && d_lineno <= 127);
+
+ len = PyBytes_GET_SIZE(a->a_lnotab);
+ if (a->a_lnotab_off + 2 >= len) {
+ if (_PyBytes_Resize(&a->a_lnotab, len * 2) < 0)
+ return 0;
+ }
+ lnotab = (unsigned char *)
+ PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
+
+ a->a_lnotab_off += 2;
+ if (d_bytecode) {
+ *lnotab++ = d_bytecode;
+ *lnotab++ = d_lineno;
+ }
+ else { /* First line of a block; def stmt, etc. */
+ *lnotab++ = 0;
+ *lnotab++ = d_lineno;
+ }
+ a->a_lineno = i->i_lineno;
+ a->a_lineno_off = a->a_offset;
+ return 1;
+}
+
+/* assemble_emit()
+ Extend the bytecode with a new instruction.
+ Update lnotab if necessary.
+*/
+
+static int
+assemble_emit(struct assembler *a, struct instr *i)
+{
+ int size, arg = 0;
+ Py_ssize_t len = PyBytes_GET_SIZE(a->a_bytecode);
+ _Py_CODEUNIT *code;
+
+ arg = i->i_oparg;
+ size = instrsize(arg);
+ if (i->i_lineno && !assemble_lnotab(a, i))
+ return 0;
+ if (a->a_offset + size >= len / (int)sizeof(_Py_CODEUNIT)) {
+ if (len > PY_SSIZE_T_MAX / 2)
+ return 0;
+ if (_PyBytes_Resize(&a->a_bytecode, len * 2) < 0)
+ return 0;
+ }
+ code = (_Py_CODEUNIT *)PyBytes_AS_STRING(a->a_bytecode) + a->a_offset;
+ a->a_offset += size;
+ write_op_arg(code, i->i_opcode, arg, size);
+ return 1;
+}
+
+static void
+assemble_jump_offsets(struct assembler *a, struct compiler *c)
+{
+ basicblock *b;
+ int bsize, totsize, extended_arg_recompile;
+ int i;
+
+ /* Compute the size of each block and fixup jump args.
+ Replace block pointer with position in bytecode. */
+ do {
+ totsize = 0;
+ for (i = a->a_nblocks - 1; i >= 0; i--) {
+ b = a->a_postorder[i];
+ bsize = blocksize(b);
+ b->b_offset = totsize;
+ totsize += bsize;
+ }
+ extended_arg_recompile = 0;
+ for (b = c->u->u_blocks; b != NULL; b = b->b_list) {
+ bsize = b->b_offset;
+ for (i = 0; i < b->b_iused; i++) {
+ struct instr *instr = &b->b_instr[i];
+ int isize = instrsize(instr->i_oparg);
+ /* Relative jumps are computed relative to
+ the instruction pointer after fetching
+ the jump instruction.
+ */
+ bsize += isize;
+ if (instr->i_jabs || instr->i_jrel) {
+ instr->i_oparg = instr->i_target->b_offset;
+ if (instr->i_jrel) {
+ instr->i_oparg -= bsize;
+ }
+ instr->i_oparg *= sizeof(_Py_CODEUNIT);
+ if (instrsize(instr->i_oparg) != isize) {
+ extended_arg_recompile = 1;
+ }
+ }
+ }
+ }
+
+ /* XXX: This is an awful hack that could hurt performance, but
+ on the bright side it should work until we come up
+ with a better solution.
+
+ The issue is that in the first loop blocksize() is called
+ which calls instrsize() which requires i_oparg be set
+ appropriately. There is a bootstrap problem because
+ i_oparg is calculated in the second loop above.
+
+ So we loop until we stop seeing new EXTENDED_ARGs.
+ The only EXTENDED_ARGs that could be popping up are
+ ones in jump instructions. So this should converge
+ fairly quickly.
+ */
+ } while (extended_arg_recompile);
+}
+
+static PyObject *
+dict_keys_inorder(PyObject *dict, Py_ssize_t offset)
+{
+ PyObject *tuple, *k, *v;
+ Py_ssize_t i, pos = 0, size = PyDict_GET_SIZE(dict);
+
+ tuple = PyTuple_New(size);
+ if (tuple == NULL)
+ return NULL;
+ while (PyDict_Next(dict, &pos, &k, &v)) {
+ i = PyLong_AS_LONG(v);
+ Py_INCREF(k);
+ assert((i - offset) < size);
+ assert((i - offset) >= 0);
+ PyTuple_SET_ITEM(tuple, i - offset, k);
+ }
+ return tuple;
+}
+
+static PyObject *
+consts_dict_keys_inorder(PyObject *dict)
+{
+ PyObject *consts, *k, *v;
+ Py_ssize_t i, pos = 0, size = PyDict_GET_SIZE(dict);
+
+ consts = PyList_New(size); /* PyCode_Optimize() requires a list */
+ if (consts == NULL)
+ return NULL;
+ while (PyDict_Next(dict, &pos, &k, &v)) {
+ i = PyLong_AS_LONG(v);
+ /* The keys of the dictionary can be tuples wrapping a contant.
+ * (see compiler_add_o and _PyCode_ConstantKey). In that case
+ * the object we want is always second. */
+ if (PyTuple_CheckExact(k)) {
+ k = PyTuple_GET_ITEM(k, 1);
+ }
+ Py_INCREF(k);
+ assert(i < size);
+ assert(i >= 0);
+ PyList_SET_ITEM(consts, i, k);
+ }
+ return consts;
+}
+
+static int
+compute_code_flags(struct compiler *c)
+{
+ PySTEntryObject *ste = c->u->u_ste;
+ int flags = 0;
+ if (ste->ste_type == FunctionBlock) {
+ flags |= CO_NEWLOCALS | CO_OPTIMIZED;
+ if (ste->ste_nested)
+ flags |= CO_NESTED;
+ if (ste->ste_generator && !ste->ste_coroutine)
+ flags |= CO_GENERATOR;
+ if (!ste->ste_generator && ste->ste_coroutine)
+ flags |= CO_COROUTINE;
+ if (ste->ste_generator && ste->ste_coroutine)
+ flags |= CO_ASYNC_GENERATOR;
+ if (ste->ste_varargs)
+ flags |= CO_VARARGS;
+ if (ste->ste_varkeywords)
+ flags |= CO_VARKEYWORDS;
+ }
+
+ /* (Only) inherit compilerflags in PyCF_MASK */
+ flags |= (c->c_flags->cf_flags & PyCF_MASK);
+
+ if ((IS_TOP_LEVEL_AWAIT(c)) &&
+ ste->ste_coroutine &&
+ !ste->ste_generator) {
+ flags |= CO_COROUTINE;
+ }
+
+ return flags;
+}
+
+// Merge *tuple* with constant cache.
+// Unlike merge_consts_recursive(), this function doesn't work recursively.
+static int
+merge_const_tuple(struct compiler *c, PyObject **tuple)
+{
+ assert(PyTuple_CheckExact(*tuple));
+
+ PyObject *key = _PyCode_ConstantKey(*tuple);
+ if (key == NULL) {
+ return 0;
+ }
+
+ // t is borrowed reference
+ PyObject *t = PyDict_SetDefault(c->c_const_cache, key, key);
+ Py_DECREF(key);
+ if (t == NULL) {
+ return 0;
+ }
+ if (t == key) { // tuple is new constant.
+ return 1;
+ }
+
+ PyObject *u = PyTuple_GET_ITEM(t, 1);
+ Py_INCREF(u);
+ Py_DECREF(*tuple);
+ *tuple = u;
+ return 1;
+}
+
+static PyCodeObject *
+makecode(struct compiler *c, struct assembler *a)
+{
+ PyObject *tmp;
+ PyCodeObject *co = NULL;
+ PyObject *consts = NULL;
+ PyObject *names = NULL;
+ PyObject *varnames = NULL;
+ PyObject *name = NULL;
+ PyObject *freevars = NULL;
+ PyObject *cellvars = NULL;
+ PyObject *bytecode = NULL;
+ Py_ssize_t nlocals;
+ int nlocals_int;
+ int flags;
+ int posorkeywordargcount, posonlyargcount, kwonlyargcount, maxdepth;
+
+ consts = consts_dict_keys_inorder(c->u->u_consts);
+ names = dict_keys_inorder(c->u->u_names, 0);
+ varnames = dict_keys_inorder(c->u->u_varnames, 0);
+ if (!consts || !names || !varnames)
+ goto error;
+
+ cellvars = dict_keys_inorder(c->u->u_cellvars, 0);
+ if (!cellvars)
+ goto error;
+ freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_GET_SIZE(cellvars));
+ if (!freevars)
+ goto error;
+
+ if (!merge_const_tuple(c, &names) ||
+ !merge_const_tuple(c, &varnames) ||
+ !merge_const_tuple(c, &cellvars) ||
+ !merge_const_tuple(c, &freevars))
+ {
+ goto error;
+ }
+
+ nlocals = PyDict_GET_SIZE(c->u->u_varnames);
+ assert(nlocals < INT_MAX);
+ nlocals_int = Py_SAFE_DOWNCAST(nlocals, Py_ssize_t, int);
+
+ flags = compute_code_flags(c);
+ if (flags < 0)
+ goto error;
+
+ bytecode = PyCode_Optimize(a->a_bytecode, consts, names, a->a_lnotab);
+ if (!bytecode)
+ goto error;
+
+ tmp = PyList_AsTuple(consts); /* PyCode_New requires a tuple */
+ if (!tmp)
+ goto error;
+ Py_DECREF(consts);
+ consts = tmp;
+ if (!merge_const_tuple(c, &consts)) {
+ goto error;
+ }
+
+ posonlyargcount = Py_SAFE_DOWNCAST(c->u->u_posonlyargcount, Py_ssize_t, int);
+ posorkeywordargcount = Py_SAFE_DOWNCAST(c->u->u_argcount, Py_ssize_t, int);
+ kwonlyargcount = Py_SAFE_DOWNCAST(c->u->u_kwonlyargcount, Py_ssize_t, int);
+ maxdepth = stackdepth(c);
+ if (maxdepth < 0) {
+ goto error;
+ }
+ co = PyCode_NewWithPosOnlyArgs(posonlyargcount+posorkeywordargcount,
+ posonlyargcount, kwonlyargcount, nlocals_int,
+ maxdepth, flags, bytecode, consts, names,
+ varnames, freevars, cellvars, c->c_filename,
+ c->u->u_name, c->u->u_firstlineno, a->a_lnotab);
+ error:
+ Py_XDECREF(consts);
+ Py_XDECREF(names);
+ Py_XDECREF(varnames);
+ Py_XDECREF(name);
+ Py_XDECREF(freevars);
+ Py_XDECREF(cellvars);
+ Py_XDECREF(bytecode);
+ return co;
+}
+
+
+/* For debugging purposes only */
+#if 0
+static void
+dump_instr(const struct instr *i)
+{
+ const char *jrel = i->i_jrel ? "jrel " : "";
+ const char *jabs = i->i_jabs ? "jabs " : "";
+ char arg[128];
+
+ *arg = '\0';
+ if (HAS_ARG(i->i_opcode)) {
+ sprintf(arg, "arg: %d ", i->i_oparg);
+ }
+ fprintf(stderr, "line: %d, opcode: %d %s%s%s\n",
+ i->i_lineno, i->i_opcode, arg, jabs, jrel);
+}
+
+static void
+dump_basicblock(const basicblock *b)
+{
+ const char *seen = b->b_seen ? "seen " : "";
+ const char *b_return = b->b_return ? "return " : "";
+ fprintf(stderr, "used: %d, depth: %d, offset: %d %s%s\n",
+ b->b_iused, b->b_startdepth, b->b_offset, seen, b_return);
+ if (b->b_instr) {
+ int i;
+ for (i = 0; i < b->b_iused; i++) {
+ fprintf(stderr, " [%02d] ", i);
+ dump_instr(b->b_instr + i);
+ }
+ }
+}
+#endif
+
+static PyCodeObject *
+assemble(struct compiler *c, int addNone)
+{
+ basicblock *b, *entryblock;
+ struct assembler a;
+ int i, j, nblocks;
+ PyCodeObject *co = NULL;
+
+ /* Make sure every block that falls off the end returns None.
+ XXX NEXT_BLOCK() isn't quite right, because if the last
+ block ends with a jump or return b_next shouldn't set.
+ */
+ if (!c->u->u_curblock->b_return) {
+ NEXT_BLOCK(c);
+ if (addNone)
+ ADDOP_LOAD_CONST(c, Py_None);
+ ADDOP(c, RETURN_VALUE);
+ }
+
+ nblocks = 0;
+ entryblock = NULL;
+ for (b = c->u->u_blocks; b != NULL; b = b->b_list) {
+ nblocks++;
+ entryblock = b;
+ }
+
+ /* Set firstlineno if it wasn't explicitly set. */
+ if (!c->u->u_firstlineno) {
+ if (entryblock && entryblock->b_instr && entryblock->b_instr->i_lineno)
+ c->u->u_firstlineno = entryblock->b_instr->i_lineno;
+ else
+ c->u->u_firstlineno = 1;
+ }
+ if (!assemble_init(&a, nblocks, c->u->u_firstlineno))
+ goto error;
+ dfs(c, entryblock, &a, nblocks);
+
+ /* Can't modify the bytecode after computing jump offsets. */
+ assemble_jump_offsets(&a, c);
+
+ /* Emit code in reverse postorder from dfs. */
+ for (i = a.a_nblocks - 1; i >= 0; i--) {
+ b = a.a_postorder[i];
+ for (j = 0; j < b->b_iused; j++)
+ if (!assemble_emit(&a, &b->b_instr[j]))
+ goto error;
+ }
+
+ if (_PyBytes_Resize(&a.a_lnotab, a.a_lnotab_off) < 0)
+ goto error;
+ if (_PyBytes_Resize(&a.a_bytecode, a.a_offset * sizeof(_Py_CODEUNIT)) < 0)
+ goto error;
+
+ co = makecode(c, &a);
+ error:
+ assemble_free(&a);
+ return co;
+}
+
+#undef PyAST_Compile
+PyCodeObject *
+PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags,
+ PyArena *arena)
+{
+ return PyAST_CompileEx(mod, filename, flags, -1, arena);
+}
diff --git a/contrib/tools/python3/src/Python/condvar.h b/contrib/tools/python3/src/Python/condvar.h
new file mode 100644
index 00000000000..8cba19b8461
--- /dev/null
+++ b/contrib/tools/python3/src/Python/condvar.h
@@ -0,0 +1,309 @@
+/*
+ * Portable condition variable support for windows and pthreads.
+ * Everything is inline, this header can be included where needed.
+ *
+ * APIs generally return 0 on success and non-zero on error,
+ * and the caller needs to use its platform's error mechanism to
+ * discover the error (errno, or GetLastError())
+ *
+ * Note that some implementations cannot distinguish between a
+ * condition variable wait time-out and successful wait. Most often
+ * the difference is moot anyway since the wait condition must be
+ * re-checked.
+ * PyCOND_TIMEDWAIT, in addition to returning negative on error,
+ * thus returns 0 on regular success, 1 on timeout
+ * or 2 if it can't tell.
+ *
+ * There are at least two caveats with using these condition variables,
+ * due to the fact that they may be emulated with Semaphores on
+ * Windows:
+ * 1) While PyCOND_SIGNAL() will wake up at least one thread, we
+ * cannot currently guarantee that it will be one of the threads
+ * already waiting in a PyCOND_WAIT() call. It _could_ cause
+ * the wakeup of a subsequent thread to try a PyCOND_WAIT(),
+ * including the thread doing the PyCOND_SIGNAL() itself.
+ * The same applies to PyCOND_BROADCAST(), if N threads are waiting
+ * then at least N threads will be woken up, but not necessarily
+ * those already waiting.
+ * For this reason, don't make the scheduling assumption that a
+ * specific other thread will get the wakeup signal
+ * 2) The _mutex_ must be held when calling PyCOND_SIGNAL() and
+ * PyCOND_BROADCAST().
+ * While e.g. the posix standard strongly recommends that the mutex
+ * associated with the condition variable is held when a
+ * pthread_cond_signal() call is made, this is not a hard requirement,
+ * although scheduling will not be "reliable" if it isn't. Here
+ * the mutex is used for internal synchronization of the emulated
+ * Condition Variable.
+ */
+
+#ifndef _CONDVAR_IMPL_H_
+#define _CONDVAR_IMPL_H_
+
+#include "Python.h"
+#include "pycore_condvar.h"
+
+#ifdef _POSIX_THREADS
+/*
+ * POSIX support
+ */
+
+/* These private functions are implemented in Python/thread_pthread.h */
+int _PyThread_cond_init(PyCOND_T *cond);
+void _PyThread_cond_after(long long us, struct timespec *abs);
+
+/* The following functions return 0 on success, nonzero on error */
+#define PyMUTEX_INIT(mut) pthread_mutex_init((mut), NULL)
+#define PyMUTEX_FINI(mut) pthread_mutex_destroy(mut)
+#define PyMUTEX_LOCK(mut) pthread_mutex_lock(mut)
+#define PyMUTEX_UNLOCK(mut) pthread_mutex_unlock(mut)
+
+#define PyCOND_INIT(cond) _PyThread_cond_init(cond)
+#define PyCOND_FINI(cond) pthread_cond_destroy(cond)
+#define PyCOND_SIGNAL(cond) pthread_cond_signal(cond)
+#define PyCOND_BROADCAST(cond) pthread_cond_broadcast(cond)
+#define PyCOND_WAIT(cond, mut) pthread_cond_wait((cond), (mut))
+
+/* return 0 for success, 1 on timeout, -1 on error */
+Py_LOCAL_INLINE(int)
+PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, long long us)
+{
+ struct timespec abs;
+ _PyThread_cond_after(us, &abs);
+ int ret = pthread_cond_timedwait(cond, mut, &abs);
+ if (ret == ETIMEDOUT) {
+ return 1;
+ }
+ if (ret) {
+ return -1;
+ }
+ return 0;
+}
+
+#elif defined(NT_THREADS)
+/*
+ * Windows (XP, 2003 server and later, as well as (hopefully) CE) support
+ *
+ * Emulated condition variables ones that work with XP and later, plus
+ * example native support on VISTA and onwards.
+ */
+
+#if _PY_EMULATED_WIN_CV
+
+/* The mutex is a CriticalSection object and
+ The condition variables is emulated with the help of a semaphore.
+
+ This implementation still has the problem that the threads woken
+ with a "signal" aren't necessarily those that are already
+ waiting. It corresponds to listing 2 in:
+ http://birrell.org/andrew/papers/ImplementingCVs.pdf
+
+ Generic emulations of the pthread_cond_* API using
+ earlier Win32 functions can be found on the Web.
+ The following read can be give background information to these issues,
+ but the implementations are all broken in some way.
+ http://www.cse.wustl.edu/~schmidt/win32-cv-1.html
+*/
+
+Py_LOCAL_INLINE(int)
+PyMUTEX_INIT(PyMUTEX_T *cs)
+{
+ InitializeCriticalSection(cs);
+ return 0;
+}
+
+Py_LOCAL_INLINE(int)
+PyMUTEX_FINI(PyMUTEX_T *cs)
+{
+ DeleteCriticalSection(cs);
+ return 0;
+}
+
+Py_LOCAL_INLINE(int)
+PyMUTEX_LOCK(PyMUTEX_T *cs)
+{
+ EnterCriticalSection(cs);
+ return 0;
+}
+
+Py_LOCAL_INLINE(int)
+PyMUTEX_UNLOCK(PyMUTEX_T *cs)
+{
+ LeaveCriticalSection(cs);
+ return 0;
+}
+
+
+Py_LOCAL_INLINE(int)
+PyCOND_INIT(PyCOND_T *cv)
+{
+ /* A semaphore with a "large" max value, The positive value
+ * is only needed to catch those "lost wakeup" events and
+ * race conditions when a timed wait elapses.
+ */
+ cv->sem = CreateSemaphore(NULL, 0, 100000, NULL);
+ if (cv->sem==NULL)
+ return -1;
+ cv->waiting = 0;
+ return 0;
+}
+
+Py_LOCAL_INLINE(int)
+PyCOND_FINI(PyCOND_T *cv)
+{
+ return CloseHandle(cv->sem) ? 0 : -1;
+}
+
+/* this implementation can detect a timeout. Returns 1 on timeout,
+ * 0 otherwise (and -1 on error)
+ */
+Py_LOCAL_INLINE(int)
+_PyCOND_WAIT_MS(PyCOND_T *cv, PyMUTEX_T *cs, DWORD ms)
+{
+ DWORD wait;
+ cv->waiting++;
+ PyMUTEX_UNLOCK(cs);
+ /* "lost wakeup bug" would occur if the caller were interrupted here,
+ * but we are safe because we are using a semaphore which has an internal
+ * count.
+ */
+ wait = WaitForSingleObjectEx(cv->sem, ms, FALSE);
+ PyMUTEX_LOCK(cs);
+ if (wait != WAIT_OBJECT_0)
+ --cv->waiting;
+ /* Here we have a benign race condition with PyCOND_SIGNAL.
+ * When failure occurs or timeout, it is possible that
+ * PyCOND_SIGNAL also decrements this value
+ * and signals releases the mutex. This is benign because it
+ * just means an extra spurious wakeup for a waiting thread.
+ * ('waiting' corresponds to the semaphore's "negative" count and
+ * we may end up with e.g. (waiting == -1 && sem.count == 1). When
+ * a new thread comes along, it will pass right through, having
+ * adjusted it to (waiting == 0 && sem.count == 0).
+ */
+
+ if (wait == WAIT_FAILED)
+ return -1;
+ /* return 0 on success, 1 on timeout */
+ return wait != WAIT_OBJECT_0;
+}
+
+Py_LOCAL_INLINE(int)
+PyCOND_WAIT(PyCOND_T *cv, PyMUTEX_T *cs)
+{
+ int result = _PyCOND_WAIT_MS(cv, cs, INFINITE);
+ return result >= 0 ? 0 : result;
+}
+
+Py_LOCAL_INLINE(int)
+PyCOND_TIMEDWAIT(PyCOND_T *cv, PyMUTEX_T *cs, long long us)
+{
+ return _PyCOND_WAIT_MS(cv, cs, (DWORD)(us/1000));
+}
+
+Py_LOCAL_INLINE(int)
+PyCOND_SIGNAL(PyCOND_T *cv)
+{
+ /* this test allows PyCOND_SIGNAL to be a no-op unless required
+ * to wake someone up, thus preventing an unbounded increase of
+ * the semaphore's internal counter.
+ */
+ if (cv->waiting > 0) {
+ /* notifying thread decreases the cv->waiting count so that
+ * a delay between notify and actual wakeup of the target thread
+ * doesn't cause a number of extra ReleaseSemaphore calls.
+ */
+ cv->waiting--;
+ return ReleaseSemaphore(cv->sem, 1, NULL) ? 0 : -1;
+ }
+ return 0;
+}
+
+Py_LOCAL_INLINE(int)
+PyCOND_BROADCAST(PyCOND_T *cv)
+{
+ int waiting = cv->waiting;
+ if (waiting > 0) {
+ cv->waiting = 0;
+ return ReleaseSemaphore(cv->sem, waiting, NULL) ? 0 : -1;
+ }
+ return 0;
+}
+
+#else /* !_PY_EMULATED_WIN_CV */
+
+Py_LOCAL_INLINE(int)
+PyMUTEX_INIT(PyMUTEX_T *cs)
+{
+ InitializeSRWLock(cs);
+ return 0;
+}
+
+Py_LOCAL_INLINE(int)
+PyMUTEX_FINI(PyMUTEX_T *cs)
+{
+ return 0;
+}
+
+Py_LOCAL_INLINE(int)
+PyMUTEX_LOCK(PyMUTEX_T *cs)
+{
+ AcquireSRWLockExclusive(cs);
+ return 0;
+}
+
+Py_LOCAL_INLINE(int)
+PyMUTEX_UNLOCK(PyMUTEX_T *cs)
+{
+ ReleaseSRWLockExclusive(cs);
+ return 0;
+}
+
+
+Py_LOCAL_INLINE(int)
+PyCOND_INIT(PyCOND_T *cv)
+{
+ InitializeConditionVariable(cv);
+ return 0;
+}
+Py_LOCAL_INLINE(int)
+PyCOND_FINI(PyCOND_T *cv)
+{
+ return 0;
+}
+
+Py_LOCAL_INLINE(int)
+PyCOND_WAIT(PyCOND_T *cv, PyMUTEX_T *cs)
+{
+ return SleepConditionVariableSRW(cv, cs, INFINITE, 0) ? 0 : -1;
+}
+
+/* This implementation makes no distinction about timeouts. Signal
+ * 2 to indicate that we don't know.
+ */
+Py_LOCAL_INLINE(int)
+PyCOND_TIMEDWAIT(PyCOND_T *cv, PyMUTEX_T *cs, long long us)
+{
+ return SleepConditionVariableSRW(cv, cs, (DWORD)(us/1000), 0) ? 2 : -1;
+}
+
+Py_LOCAL_INLINE(int)
+PyCOND_SIGNAL(PyCOND_T *cv)
+{
+ WakeConditionVariable(cv);
+ return 0;
+}
+
+Py_LOCAL_INLINE(int)
+PyCOND_BROADCAST(PyCOND_T *cv)
+{
+ WakeAllConditionVariable(cv);
+ return 0;
+}
+
+
+#endif /* _PY_EMULATED_WIN_CV */
+
+#endif /* _POSIX_THREADS, NT_THREADS */
+
+#endif /* _CONDVAR_IMPL_H_ */
diff --git a/contrib/tools/python3/src/Python/context.c b/contrib/tools/python3/src/Python/context.c
new file mode 100644
index 00000000000..bacc7010c45
--- /dev/null
+++ b/contrib/tools/python3/src/Python/context.c
@@ -0,0 +1,1319 @@
+#include "Python.h"
+
+#include "pycore_context.h"
+#include "pycore_gc.h" // _PyObject_GC_MAY_BE_TRACKED()
+#include "pycore_hamt.h"
+#include "pycore_object.h"
+#include "pycore_pyerrors.h"
+#include "pycore_pystate.h" // _PyThreadState_GET()
+#include "structmember.h" // PyMemberDef
+
+
+#define CONTEXT_FREELIST_MAXLEN 255
+static PyContext *ctx_freelist = NULL;
+static int ctx_freelist_len = 0;
+
+
+#include "clinic/context.c.h"
+/*[clinic input]
+module _contextvars
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a0955718c8b8cea6]*/
+
+
+#define ENSURE_Context(o, err_ret) \
+ if (!PyContext_CheckExact(o)) { \
+ PyErr_SetString(PyExc_TypeError, \
+ "an instance of Context was expected"); \
+ return err_ret; \
+ }
+
+#define ENSURE_ContextVar(o, err_ret) \
+ if (!PyContextVar_CheckExact(o)) { \
+ PyErr_SetString(PyExc_TypeError, \
+ "an instance of ContextVar was expected"); \
+ return err_ret; \
+ }
+
+#define ENSURE_ContextToken(o, err_ret) \
+ if (!PyContextToken_CheckExact(o)) { \
+ PyErr_SetString(PyExc_TypeError, \
+ "an instance of Token was expected"); \
+ return err_ret; \
+ }
+
+
+/////////////////////////// Context API
+
+
+static PyContext *
+context_new_empty(void);
+
+static PyContext *
+context_new_from_vars(PyHamtObject *vars);
+
+static inline PyContext *
+context_get(void);
+
+static PyContextToken *
+token_new(PyContext *ctx, PyContextVar *var, PyObject *val);
+
+static PyContextVar *
+contextvar_new(PyObject *name, PyObject *def);
+
+static int
+contextvar_set(PyContextVar *var, PyObject *val);
+
+static int
+contextvar_del(PyContextVar *var);
+
+
+PyObject *
+_PyContext_NewHamtForTests(void)
+{
+ return (PyObject *)_PyHamt_New();
+}
+
+
+PyObject *
+PyContext_New(void)
+{
+ return (PyObject *)context_new_empty();
+}
+
+
+PyObject *
+PyContext_Copy(PyObject * octx)
+{
+ ENSURE_Context(octx, NULL)
+ PyContext *ctx = (PyContext *)octx;
+ return (PyObject *)context_new_from_vars(ctx->ctx_vars);
+}
+
+
+PyObject *
+PyContext_CopyCurrent(void)
+{
+ PyContext *ctx = context_get();
+ if (ctx == NULL) {
+ return NULL;
+ }
+
+ return (PyObject *)context_new_from_vars(ctx->ctx_vars);
+}
+
+
+static int
+_PyContext_Enter(PyThreadState *ts, PyObject *octx)
+{
+ ENSURE_Context(octx, -1)
+ PyContext *ctx = (PyContext *)octx;
+
+ if (ctx->ctx_entered) {
+ _PyErr_Format(ts, PyExc_RuntimeError,
+ "cannot enter context: %R is already entered", ctx);
+ return -1;
+ }
+
+ ctx->ctx_prev = (PyContext *)ts->context; /* borrow */
+ ctx->ctx_entered = 1;
+
+ Py_INCREF(ctx);
+ ts->context = (PyObject *)ctx;
+ ts->context_ver++;
+
+ return 0;
+}
+
+
+int
+PyContext_Enter(PyObject *octx)
+{
+ PyThreadState *ts = _PyThreadState_GET();
+ assert(ts != NULL);
+ return _PyContext_Enter(ts, octx);
+}
+
+
+static int
+_PyContext_Exit(PyThreadState *ts, PyObject *octx)
+{
+ ENSURE_Context(octx, -1)
+ PyContext *ctx = (PyContext *)octx;
+
+ if (!ctx->ctx_entered) {
+ PyErr_Format(PyExc_RuntimeError,
+ "cannot exit context: %R has not been entered", ctx);
+ return -1;
+ }
+
+ if (ts->context != (PyObject *)ctx) {
+ /* Can only happen if someone misuses the C API */
+ PyErr_SetString(PyExc_RuntimeError,
+ "cannot exit context: thread state references "
+ "a different context object");
+ return -1;
+ }
+
+ Py_SETREF(ts->context, (PyObject *)ctx->ctx_prev);
+ ts->context_ver++;
+
+ ctx->ctx_prev = NULL;
+ ctx->ctx_entered = 0;
+
+ return 0;
+}
+
+int
+PyContext_Exit(PyObject *octx)
+{
+ PyThreadState *ts = _PyThreadState_GET();
+ assert(ts != NULL);
+ return _PyContext_Exit(ts, octx);
+}
+
+
+PyObject *
+PyContextVar_New(const char *name, PyObject *def)
+{
+ PyObject *pyname = PyUnicode_FromString(name);
+ if (pyname == NULL) {
+ return NULL;
+ }
+ PyContextVar *var = contextvar_new(pyname, def);
+ Py_DECREF(pyname);
+ return (PyObject *)var;
+}
+
+
+int
+PyContextVar_Get(PyObject *ovar, PyObject *def, PyObject **val)
+{
+ ENSURE_ContextVar(ovar, -1)
+ PyContextVar *var = (PyContextVar *)ovar;
+
+ PyThreadState *ts = _PyThreadState_GET();
+ assert(ts != NULL);
+ if (ts->context == NULL) {
+ goto not_found;
+ }
+
+ if (var->var_cached != NULL &&
+ var->var_cached_tsid == ts->id &&
+ var->var_cached_tsver == ts->context_ver)
+ {
+ *val = var->var_cached;
+ goto found;
+ }
+
+ assert(PyContext_CheckExact(ts->context));
+ PyHamtObject *vars = ((PyContext *)ts->context)->ctx_vars;
+
+ PyObject *found = NULL;
+ int res = _PyHamt_Find(vars, (PyObject*)var, &found);
+ if (res < 0) {
+ goto error;
+ }
+ if (res == 1) {
+ assert(found != NULL);
+ var->var_cached = found; /* borrow */
+ var->var_cached_tsid = ts->id;
+ var->var_cached_tsver = ts->context_ver;
+
+ *val = found;
+ goto found;
+ }
+
+not_found:
+ if (def == NULL) {
+ if (var->var_default != NULL) {
+ *val = var->var_default;
+ goto found;
+ }
+
+ *val = NULL;
+ goto found;
+ }
+ else {
+ *val = def;
+ goto found;
+ }
+
+found:
+ Py_XINCREF(*val);
+ return 0;
+
+error:
+ *val = NULL;
+ return -1;
+}
+
+
+PyObject *
+PyContextVar_Set(PyObject *ovar, PyObject *val)
+{
+ ENSURE_ContextVar(ovar, NULL)
+ PyContextVar *var = (PyContextVar *)ovar;
+
+ if (!PyContextVar_CheckExact(var)) {
+ PyErr_SetString(
+ PyExc_TypeError, "an instance of ContextVar was expected");
+ return NULL;
+ }
+
+ PyContext *ctx = context_get();
+ if (ctx == NULL) {
+ return NULL;
+ }
+
+ PyObject *old_val = NULL;
+ int found = _PyHamt_Find(ctx->ctx_vars, (PyObject *)var, &old_val);
+ if (found < 0) {
+ return NULL;
+ }
+
+ Py_XINCREF(old_val);
+ PyContextToken *tok = token_new(ctx, var, old_val);
+ Py_XDECREF(old_val);
+
+ if (contextvar_set(var, val)) {
+ Py_DECREF(tok);
+ return NULL;
+ }
+
+ return (PyObject *)tok;
+}
+
+
+int
+PyContextVar_Reset(PyObject *ovar, PyObject *otok)
+{
+ ENSURE_ContextVar(ovar, -1)
+ ENSURE_ContextToken(otok, -1)
+ PyContextVar *var = (PyContextVar *)ovar;
+ PyContextToken *tok = (PyContextToken *)otok;
+
+ if (tok->tok_used) {
+ PyErr_Format(PyExc_RuntimeError,
+ "%R has already been used once", tok);
+ return -1;
+ }
+
+ if (var != tok->tok_var) {
+ PyErr_Format(PyExc_ValueError,
+ "%R was created by a different ContextVar", tok);
+ return -1;
+ }
+
+ PyContext *ctx = context_get();
+ if (ctx != tok->tok_ctx) {
+ PyErr_Format(PyExc_ValueError,
+ "%R was created in a different Context", tok);
+ return -1;
+ }
+
+ tok->tok_used = 1;
+
+ if (tok->tok_oldval == NULL) {
+ return contextvar_del(var);
+ }
+ else {
+ return contextvar_set(var, tok->tok_oldval);
+ }
+}
+
+
+/////////////////////////// PyContext
+
+/*[clinic input]
+class _contextvars.Context "PyContext *" "&PyContext_Type"
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=bdf87f8e0cb580e8]*/
+
+
+static inline PyContext *
+_context_alloc(void)
+{
+ PyContext *ctx;
+ if (ctx_freelist_len) {
+ ctx_freelist_len--;
+ ctx = ctx_freelist;
+ ctx_freelist = (PyContext *)ctx->ctx_weakreflist;
+ ctx->ctx_weakreflist = NULL;
+ _Py_NewReference((PyObject *)ctx);
+ }
+ else {
+ ctx = PyObject_GC_New(PyContext, &PyContext_Type);
+ if (ctx == NULL) {
+ return NULL;
+ }
+ }
+
+ ctx->ctx_vars = NULL;
+ ctx->ctx_prev = NULL;
+ ctx->ctx_entered = 0;
+ ctx->ctx_weakreflist = NULL;
+
+ return ctx;
+}
+
+
+static PyContext *
+context_new_empty(void)
+{
+ PyContext *ctx = _context_alloc();
+ if (ctx == NULL) {
+ return NULL;
+ }
+
+ ctx->ctx_vars = _PyHamt_New();
+ if (ctx->ctx_vars == NULL) {
+ Py_DECREF(ctx);
+ return NULL;
+ }
+
+ _PyObject_GC_TRACK(ctx);
+ return ctx;
+}
+
+
+static PyContext *
+context_new_from_vars(PyHamtObject *vars)
+{
+ PyContext *ctx = _context_alloc();
+ if (ctx == NULL) {
+ return NULL;
+ }
+
+ Py_INCREF(vars);
+ ctx->ctx_vars = vars;
+
+ _PyObject_GC_TRACK(ctx);
+ return ctx;
+}
+
+
+static inline PyContext *
+context_get(void)
+{
+ PyThreadState *ts = _PyThreadState_GET();
+ assert(ts != NULL);
+ PyContext *current_ctx = (PyContext *)ts->context;
+ if (current_ctx == NULL) {
+ current_ctx = context_new_empty();
+ if (current_ctx == NULL) {
+ return NULL;
+ }
+ ts->context = (PyObject *)current_ctx;
+ }
+ return current_ctx;
+}
+
+static int
+context_check_key_type(PyObject *key)
+{
+ if (!PyContextVar_CheckExact(key)) {
+ // abort();
+ PyErr_Format(PyExc_TypeError,
+ "a ContextVar key was expected, got %R", key);
+ return -1;
+ }
+ return 0;
+}
+
+static PyObject *
+context_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ if (PyTuple_Size(args) || (kwds != NULL && PyDict_Size(kwds))) {
+ PyErr_SetString(
+ PyExc_TypeError, "Context() does not accept any arguments");
+ return NULL;
+ }
+ return PyContext_New();
+}
+
+static int
+context_tp_clear(PyContext *self)
+{
+ Py_CLEAR(self->ctx_prev);
+ Py_CLEAR(self->ctx_vars);
+ return 0;
+}
+
+static int
+context_tp_traverse(PyContext *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->ctx_prev);
+ Py_VISIT(self->ctx_vars);
+ return 0;
+}
+
+static void
+context_tp_dealloc(PyContext *self)
+{
+ _PyObject_GC_UNTRACK(self);
+
+ if (self->ctx_weakreflist != NULL) {
+ PyObject_ClearWeakRefs((PyObject*)self);
+ }
+ (void)context_tp_clear(self);
+
+ if (ctx_freelist_len < CONTEXT_FREELIST_MAXLEN) {
+ ctx_freelist_len++;
+ self->ctx_weakreflist = (PyObject *)ctx_freelist;
+ ctx_freelist = self;
+ }
+ else {
+ Py_TYPE(self)->tp_free(self);
+ }
+}
+
+static PyObject *
+context_tp_iter(PyContext *self)
+{
+ return _PyHamt_NewIterKeys(self->ctx_vars);
+}
+
+static PyObject *
+context_tp_richcompare(PyObject *v, PyObject *w, int op)
+{
+ if (!PyContext_CheckExact(v) || !PyContext_CheckExact(w) ||
+ (op != Py_EQ && op != Py_NE))
+ {
+ Py_RETURN_NOTIMPLEMENTED;
+ }
+
+ int res = _PyHamt_Eq(
+ ((PyContext *)v)->ctx_vars, ((PyContext *)w)->ctx_vars);
+ if (res < 0) {
+ return NULL;
+ }
+
+ if (op == Py_NE) {
+ res = !res;
+ }
+
+ if (res) {
+ Py_RETURN_TRUE;
+ }
+ else {
+ Py_RETURN_FALSE;
+ }
+}
+
+static Py_ssize_t
+context_tp_len(PyContext *self)
+{
+ return _PyHamt_Len(self->ctx_vars);
+}
+
+static PyObject *
+context_tp_subscript(PyContext *self, PyObject *key)
+{
+ if (context_check_key_type(key)) {
+ return NULL;
+ }
+ PyObject *val = NULL;
+ int found = _PyHamt_Find(self->ctx_vars, key, &val);
+ if (found < 0) {
+ return NULL;
+ }
+ if (found == 0) {
+ PyErr_SetObject(PyExc_KeyError, key);
+ return NULL;
+ }
+ Py_INCREF(val);
+ return val;
+}
+
+static int
+context_tp_contains(PyContext *self, PyObject *key)
+{
+ if (context_check_key_type(key)) {
+ return -1;
+ }
+ PyObject *val = NULL;
+ return _PyHamt_Find(self->ctx_vars, key, &val);
+}
+
+
+/*[clinic input]
+_contextvars.Context.get
+ key: object
+ default: object = None
+ /
+
+Return the value for `key` if `key` has the value in the context object.
+
+If `key` does not exist, return `default`. If `default` is not given,
+return None.
+[clinic start generated code]*/
+
+static PyObject *
+_contextvars_Context_get_impl(PyContext *self, PyObject *key,
+ PyObject *default_value)
+/*[clinic end generated code: output=0c54aa7664268189 input=c8eeb81505023995]*/
+{
+ if (context_check_key_type(key)) {
+ return NULL;
+ }
+
+ PyObject *val = NULL;
+ int found = _PyHamt_Find(self->ctx_vars, key, &val);
+ if (found < 0) {
+ return NULL;
+ }
+ if (found == 0) {
+ Py_INCREF(default_value);
+ return default_value;
+ }
+ Py_INCREF(val);
+ return val;
+}
+
+
+/*[clinic input]
+_contextvars.Context.items
+
+Return all variables and their values in the context object.
+
+The result is returned as a list of 2-tuples (variable, value).
+[clinic start generated code]*/
+
+static PyObject *
+_contextvars_Context_items_impl(PyContext *self)
+/*[clinic end generated code: output=fa1655c8a08502af input=00db64ae379f9f42]*/
+{
+ return _PyHamt_NewIterItems(self->ctx_vars);
+}
+
+
+/*[clinic input]
+_contextvars.Context.keys
+
+Return a list of all variables in the context object.
+[clinic start generated code]*/
+
+static PyObject *
+_contextvars_Context_keys_impl(PyContext *self)
+/*[clinic end generated code: output=177227c6b63ec0e2 input=114b53aebca3449c]*/
+{
+ return _PyHamt_NewIterKeys(self->ctx_vars);
+}
+
+
+/*[clinic input]
+_contextvars.Context.values
+
+Return a list of all variables' values in the context object.
+[clinic start generated code]*/
+
+static PyObject *
+_contextvars_Context_values_impl(PyContext *self)
+/*[clinic end generated code: output=d286dabfc8db6dde input=ce8075d04a6ea526]*/
+{
+ return _PyHamt_NewIterValues(self->ctx_vars);
+}
+
+
+/*[clinic input]
+_contextvars.Context.copy
+
+Return a shallow copy of the context object.
+[clinic start generated code]*/
+
+static PyObject *
+_contextvars_Context_copy_impl(PyContext *self)
+/*[clinic end generated code: output=30ba8896c4707a15 input=ebafdbdd9c72d592]*/
+{
+ return (PyObject *)context_new_from_vars(self->ctx_vars);
+}
+
+
+static PyObject *
+context_run(PyContext *self, PyObject *const *args,
+ Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyThreadState *ts = _PyThreadState_GET();
+
+ if (nargs < 1) {
+ _PyErr_SetString(ts, PyExc_TypeError,
+ "run() missing 1 required positional argument");
+ return NULL;
+ }
+
+ if (_PyContext_Enter(ts, (PyObject *)self)) {
+ return NULL;
+ }
+
+ PyObject *call_result = _PyObject_VectorcallTstate(
+ ts, args[0], args + 1, nargs - 1, kwnames);
+
+ if (_PyContext_Exit(ts, (PyObject *)self)) {
+ return NULL;
+ }
+
+ return call_result;
+}
+
+
+static PyMethodDef PyContext_methods[] = {
+ _CONTEXTVARS_CONTEXT_GET_METHODDEF
+ _CONTEXTVARS_CONTEXT_ITEMS_METHODDEF
+ _CONTEXTVARS_CONTEXT_KEYS_METHODDEF
+ _CONTEXTVARS_CONTEXT_VALUES_METHODDEF
+ _CONTEXTVARS_CONTEXT_COPY_METHODDEF
+ {"run", (PyCFunction)(void(*)(void))context_run, METH_FASTCALL | METH_KEYWORDS, NULL},
+ {NULL, NULL}
+};
+
+static PySequenceMethods PyContext_as_sequence = {
+ 0, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ 0, /* sq_item */
+ 0, /* sq_slice */
+ 0, /* sq_ass_item */
+ 0, /* sq_ass_slice */
+ (objobjproc)context_tp_contains, /* sq_contains */
+ 0, /* sq_inplace_concat */
+ 0, /* sq_inplace_repeat */
+};
+
+static PyMappingMethods PyContext_as_mapping = {
+ (lenfunc)context_tp_len, /* mp_length */
+ (binaryfunc)context_tp_subscript, /* mp_subscript */
+};
+
+PyTypeObject PyContext_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "Context",
+ sizeof(PyContext),
+ .tp_methods = PyContext_methods,
+ .tp_as_mapping = &PyContext_as_mapping,
+ .tp_as_sequence = &PyContext_as_sequence,
+ .tp_iter = (getiterfunc)context_tp_iter,
+ .tp_dealloc = (destructor)context_tp_dealloc,
+ .tp_getattro = PyObject_GenericGetAttr,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+ .tp_richcompare = context_tp_richcompare,
+ .tp_traverse = (traverseproc)context_tp_traverse,
+ .tp_clear = (inquiry)context_tp_clear,
+ .tp_new = context_tp_new,
+ .tp_weaklistoffset = offsetof(PyContext, ctx_weakreflist),
+ .tp_hash = PyObject_HashNotImplemented,
+};
+
+
+/////////////////////////// ContextVar
+
+
+static int
+contextvar_set(PyContextVar *var, PyObject *val)
+{
+ var->var_cached = NULL;
+ PyThreadState *ts = PyThreadState_Get();
+
+ PyContext *ctx = context_get();
+ if (ctx == NULL) {
+ return -1;
+ }
+
+ PyHamtObject *new_vars = _PyHamt_Assoc(
+ ctx->ctx_vars, (PyObject *)var, val);
+ if (new_vars == NULL) {
+ return -1;
+ }
+
+ Py_SETREF(ctx->ctx_vars, new_vars);
+
+ var->var_cached = val; /* borrow */
+ var->var_cached_tsid = ts->id;
+ var->var_cached_tsver = ts->context_ver;
+ return 0;
+}
+
+static int
+contextvar_del(PyContextVar *var)
+{
+ var->var_cached = NULL;
+
+ PyContext *ctx = context_get();
+ if (ctx == NULL) {
+ return -1;
+ }
+
+ PyHamtObject *vars = ctx->ctx_vars;
+ PyHamtObject *new_vars = _PyHamt_Without(vars, (PyObject *)var);
+ if (new_vars == NULL) {
+ return -1;
+ }
+
+ if (vars == new_vars) {
+ Py_DECREF(new_vars);
+ PyErr_SetObject(PyExc_LookupError, (PyObject *)var);
+ return -1;
+ }
+
+ Py_SETREF(ctx->ctx_vars, new_vars);
+ return 0;
+}
+
+static Py_hash_t
+contextvar_generate_hash(void *addr, PyObject *name)
+{
+ /* Take hash of `name` and XOR it with the object's addr.
+
+ The structure of the tree is encoded in objects' hashes, which
+ means that sufficiently similar hashes would result in tall trees
+ with many Collision nodes. Which would, in turn, result in slower
+ get and set operations.
+
+ The XORing helps to ensure that:
+
+ (1) sequentially allocated ContextVar objects have
+ different hashes;
+
+ (2) context variables with equal names have
+ different hashes.
+ */
+
+ Py_hash_t name_hash = PyObject_Hash(name);
+ if (name_hash == -1) {
+ return -1;
+ }
+
+ Py_hash_t res = _Py_HashPointer(addr) ^ name_hash;
+ return res == -1 ? -2 : res;
+}
+
+static PyContextVar *
+contextvar_new(PyObject *name, PyObject *def)
+{
+ if (!PyUnicode_Check(name)) {
+ PyErr_SetString(PyExc_TypeError,
+ "context variable name must be a str");
+ return NULL;
+ }
+
+ PyContextVar *var = PyObject_GC_New(PyContextVar, &PyContextVar_Type);
+ if (var == NULL) {
+ return NULL;
+ }
+
+ var->var_hash = contextvar_generate_hash(var, name);
+ if (var->var_hash == -1) {
+ Py_DECREF(var);
+ return NULL;
+ }
+
+ Py_INCREF(name);
+ var->var_name = name;
+
+ Py_XINCREF(def);
+ var->var_default = def;
+
+ var->var_cached = NULL;
+ var->var_cached_tsid = 0;
+ var->var_cached_tsver = 0;
+
+ if (_PyObject_GC_MAY_BE_TRACKED(name) ||
+ (def != NULL && _PyObject_GC_MAY_BE_TRACKED(def)))
+ {
+ PyObject_GC_Track(var);
+ }
+ return var;
+}
+
+
+/*[clinic input]
+class _contextvars.ContextVar "PyContextVar *" "&PyContextVar_Type"
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=445da935fa8883c3]*/
+
+
+static PyObject *
+contextvar_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"", "default", NULL};
+ PyObject *name;
+ PyObject *def = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kwds, "O|$O:ContextVar", kwlist, &name, &def))
+ {
+ return NULL;
+ }
+
+ return (PyObject *)contextvar_new(name, def);
+}
+
+static int
+contextvar_tp_clear(PyContextVar *self)
+{
+ Py_CLEAR(self->var_name);
+ Py_CLEAR(self->var_default);
+ self->var_cached = NULL;
+ self->var_cached_tsid = 0;
+ self->var_cached_tsver = 0;
+ return 0;
+}
+
+static int
+contextvar_tp_traverse(PyContextVar *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->var_name);
+ Py_VISIT(self->var_default);
+ return 0;
+}
+
+static void
+contextvar_tp_dealloc(PyContextVar *self)
+{
+ PyObject_GC_UnTrack(self);
+ (void)contextvar_tp_clear(self);
+ Py_TYPE(self)->tp_free(self);
+}
+
+static Py_hash_t
+contextvar_tp_hash(PyContextVar *self)
+{
+ return self->var_hash;
+}
+
+static PyObject *
+contextvar_tp_repr(PyContextVar *self)
+{
+ _PyUnicodeWriter writer;
+
+ _PyUnicodeWriter_Init(&writer);
+
+ if (_PyUnicodeWriter_WriteASCIIString(
+ &writer, "<ContextVar name=", 17) < 0)
+ {
+ goto error;
+ }
+
+ PyObject *name = PyObject_Repr(self->var_name);
+ if (name == NULL) {
+ goto error;
+ }
+ if (_PyUnicodeWriter_WriteStr(&writer, name) < 0) {
+ Py_DECREF(name);
+ goto error;
+ }
+ Py_DECREF(name);
+
+ if (self->var_default != NULL) {
+ if (_PyUnicodeWriter_WriteASCIIString(&writer, " default=", 9) < 0) {
+ goto error;
+ }
+
+ PyObject *def = PyObject_Repr(self->var_default);
+ if (def == NULL) {
+ goto error;
+ }
+ if (_PyUnicodeWriter_WriteStr(&writer, def) < 0) {
+ Py_DECREF(def);
+ goto error;
+ }
+ Py_DECREF(def);
+ }
+
+ PyObject *addr = PyUnicode_FromFormat(" at %p>", self);
+ if (addr == NULL) {
+ goto error;
+ }
+ if (_PyUnicodeWriter_WriteStr(&writer, addr) < 0) {
+ Py_DECREF(addr);
+ goto error;
+ }
+ Py_DECREF(addr);
+
+ return _PyUnicodeWriter_Finish(&writer);
+
+error:
+ _PyUnicodeWriter_Dealloc(&writer);
+ return NULL;
+}
+
+
+/*[clinic input]
+_contextvars.ContextVar.get
+ default: object = NULL
+ /
+
+Return a value for the context variable for the current context.
+
+If there is no value for the variable in the current context, the method will:
+ * return the value of the default argument of the method, if provided; or
+ * return the default value for the context variable, if it was created
+ with one; or
+ * raise a LookupError.
+[clinic start generated code]*/
+
+static PyObject *
+_contextvars_ContextVar_get_impl(PyContextVar *self, PyObject *default_value)
+/*[clinic end generated code: output=0746bd0aa2ced7bf input=30aa2ab9e433e401]*/
+{
+ if (!PyContextVar_CheckExact(self)) {
+ PyErr_SetString(
+ PyExc_TypeError, "an instance of ContextVar was expected");
+ return NULL;
+ }
+
+ PyObject *val;
+ if (PyContextVar_Get((PyObject *)self, default_value, &val) < 0) {
+ return NULL;
+ }
+
+ if (val == NULL) {
+ PyErr_SetObject(PyExc_LookupError, (PyObject *)self);
+ return NULL;
+ }
+
+ return val;
+}
+
+/*[clinic input]
+_contextvars.ContextVar.set
+ value: object
+ /
+
+Call to set a new value for the context variable in the current context.
+
+The required value argument is the new value for the context variable.
+
+Returns a Token object that can be used to restore the variable to its previous
+value via the `ContextVar.reset()` method.
+[clinic start generated code]*/
+
+static PyObject *
+_contextvars_ContextVar_set(PyContextVar *self, PyObject *value)
+/*[clinic end generated code: output=446ed5e820d6d60b input=c0a6887154227453]*/
+{
+ return PyContextVar_Set((PyObject *)self, value);
+}
+
+/*[clinic input]
+_contextvars.ContextVar.reset
+ token: object
+ /
+
+Reset the context variable.
+
+The variable is reset to the value it had before the `ContextVar.set()` that
+created the token was used.
+[clinic start generated code]*/
+
+static PyObject *
+_contextvars_ContextVar_reset(PyContextVar *self, PyObject *token)
+/*[clinic end generated code: output=d4ee34d0742d62ee input=ebe2881e5af4ffda]*/
+{
+ if (!PyContextToken_CheckExact(token)) {
+ PyErr_Format(PyExc_TypeError,
+ "expected an instance of Token, got %R", token);
+ return NULL;
+ }
+
+ if (PyContextVar_Reset((PyObject *)self, token)) {
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
+
+static PyMemberDef PyContextVar_members[] = {
+ {"name", T_OBJECT, offsetof(PyContextVar, var_name), READONLY},
+ {NULL}
+};
+
+static PyMethodDef PyContextVar_methods[] = {
+ _CONTEXTVARS_CONTEXTVAR_GET_METHODDEF
+ _CONTEXTVARS_CONTEXTVAR_SET_METHODDEF
+ _CONTEXTVARS_CONTEXTVAR_RESET_METHODDEF
+ {"__class_getitem__", (PyCFunction)Py_GenericAlias,
+ METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
+ {NULL, NULL}
+};
+
+PyTypeObject PyContextVar_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "ContextVar",
+ sizeof(PyContextVar),
+ .tp_methods = PyContextVar_methods,
+ .tp_members = PyContextVar_members,
+ .tp_dealloc = (destructor)contextvar_tp_dealloc,
+ .tp_getattro = PyObject_GenericGetAttr,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+ .tp_traverse = (traverseproc)contextvar_tp_traverse,
+ .tp_clear = (inquiry)contextvar_tp_clear,
+ .tp_new = contextvar_tp_new,
+ .tp_free = PyObject_GC_Del,
+ .tp_hash = (hashfunc)contextvar_tp_hash,
+ .tp_repr = (reprfunc)contextvar_tp_repr,
+};
+
+
+/////////////////////////// Token
+
+static PyObject * get_token_missing(void);
+
+
+/*[clinic input]
+class _contextvars.Token "PyContextToken *" "&PyContextToken_Type"
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=338a5e2db13d3f5b]*/
+
+
+static PyObject *
+token_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyErr_SetString(PyExc_RuntimeError,
+ "Tokens can only be created by ContextVars");
+ return NULL;
+}
+
+static int
+token_tp_clear(PyContextToken *self)
+{
+ Py_CLEAR(self->tok_ctx);
+ Py_CLEAR(self->tok_var);
+ Py_CLEAR(self->tok_oldval);
+ return 0;
+}
+
+static int
+token_tp_traverse(PyContextToken *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->tok_ctx);
+ Py_VISIT(self->tok_var);
+ Py_VISIT(self->tok_oldval);
+ return 0;
+}
+
+static void
+token_tp_dealloc(PyContextToken *self)
+{
+ PyObject_GC_UnTrack(self);
+ (void)token_tp_clear(self);
+ Py_TYPE(self)->tp_free(self);
+}
+
+static PyObject *
+token_tp_repr(PyContextToken *self)
+{
+ _PyUnicodeWriter writer;
+
+ _PyUnicodeWriter_Init(&writer);
+
+ if (_PyUnicodeWriter_WriteASCIIString(&writer, "<Token", 6) < 0) {
+ goto error;
+ }
+
+ if (self->tok_used) {
+ if (_PyUnicodeWriter_WriteASCIIString(&writer, " used", 5) < 0) {
+ goto error;
+ }
+ }
+
+ if (_PyUnicodeWriter_WriteASCIIString(&writer, " var=", 5) < 0) {
+ goto error;
+ }
+
+ PyObject *var = PyObject_Repr((PyObject *)self->tok_var);
+ if (var == NULL) {
+ goto error;
+ }
+ if (_PyUnicodeWriter_WriteStr(&writer, var) < 0) {
+ Py_DECREF(var);
+ goto error;
+ }
+ Py_DECREF(var);
+
+ PyObject *addr = PyUnicode_FromFormat(" at %p>", self);
+ if (addr == NULL) {
+ goto error;
+ }
+ if (_PyUnicodeWriter_WriteStr(&writer, addr) < 0) {
+ Py_DECREF(addr);
+ goto error;
+ }
+ Py_DECREF(addr);
+
+ return _PyUnicodeWriter_Finish(&writer);
+
+error:
+ _PyUnicodeWriter_Dealloc(&writer);
+ return NULL;
+}
+
+static PyObject *
+token_get_var(PyContextToken *self, void *Py_UNUSED(ignored))
+{
+ Py_INCREF(self->tok_var);
+ return (PyObject *)self->tok_var;
+}
+
+static PyObject *
+token_get_old_value(PyContextToken *self, void *Py_UNUSED(ignored))
+{
+ if (self->tok_oldval == NULL) {
+ return get_token_missing();
+ }
+
+ Py_INCREF(self->tok_oldval);
+ return self->tok_oldval;
+}
+
+static PyGetSetDef PyContextTokenType_getsetlist[] = {
+ {"var", (getter)token_get_var, NULL, NULL},
+ {"old_value", (getter)token_get_old_value, NULL, NULL},
+ {NULL}
+};
+
+static PyMethodDef PyContextTokenType_methods[] = {
+ {"__class_getitem__", (PyCFunction)Py_GenericAlias,
+ METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
+ {NULL}
+};
+
+PyTypeObject PyContextToken_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "Token",
+ sizeof(PyContextToken),
+ .tp_methods = PyContextTokenType_methods,
+ .tp_getset = PyContextTokenType_getsetlist,
+ .tp_dealloc = (destructor)token_tp_dealloc,
+ .tp_getattro = PyObject_GenericGetAttr,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+ .tp_traverse = (traverseproc)token_tp_traverse,
+ .tp_clear = (inquiry)token_tp_clear,
+ .tp_new = token_tp_new,
+ .tp_free = PyObject_GC_Del,
+ .tp_hash = PyObject_HashNotImplemented,
+ .tp_repr = (reprfunc)token_tp_repr,
+};
+
+static PyContextToken *
+token_new(PyContext *ctx, PyContextVar *var, PyObject *val)
+{
+ PyContextToken *tok = PyObject_GC_New(PyContextToken, &PyContextToken_Type);
+ if (tok == NULL) {
+ return NULL;
+ }
+
+ Py_INCREF(ctx);
+ tok->tok_ctx = ctx;
+
+ Py_INCREF(var);
+ tok->tok_var = var;
+
+ Py_XINCREF(val);
+ tok->tok_oldval = val;
+
+ tok->tok_used = 0;
+
+ PyObject_GC_Track(tok);
+ return tok;
+}
+
+
+/////////////////////////// Token.MISSING
+
+
+static PyObject *_token_missing;
+
+
+typedef struct {
+ PyObject_HEAD
+} PyContextTokenMissing;
+
+
+static PyObject *
+context_token_missing_tp_repr(PyObject *self)
+{
+ return PyUnicode_FromString("<Token.MISSING>");
+}
+
+
+PyTypeObject PyContextTokenMissing_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "Token.MISSING",
+ sizeof(PyContextTokenMissing),
+ .tp_getattro = PyObject_GenericGetAttr,
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_repr = context_token_missing_tp_repr,
+};
+
+
+static PyObject *
+get_token_missing(void)
+{
+ if (_token_missing != NULL) {
+ Py_INCREF(_token_missing);
+ return _token_missing;
+ }
+
+ _token_missing = (PyObject *)PyObject_New(
+ PyContextTokenMissing, &PyContextTokenMissing_Type);
+ if (_token_missing == NULL) {
+ return NULL;
+ }
+
+ Py_INCREF(_token_missing);
+ return _token_missing;
+}
+
+
+///////////////////////////
+
+
+void
+_PyContext_ClearFreeList(void)
+{
+ for (; ctx_freelist_len; ctx_freelist_len--) {
+ PyContext *ctx = ctx_freelist;
+ ctx_freelist = (PyContext *)ctx->ctx_weakreflist;
+ ctx->ctx_weakreflist = NULL;
+ PyObject_GC_Del(ctx);
+ }
+}
+
+
+void
+_PyContext_Fini(void)
+{
+ Py_CLEAR(_token_missing);
+ _PyContext_ClearFreeList();
+ _PyHamt_Fini();
+}
+
+
+int
+_PyContext_Init(void)
+{
+ if (!_PyHamt_Init()) {
+ return 0;
+ }
+
+ if ((PyType_Ready(&PyContext_Type) < 0) ||
+ (PyType_Ready(&PyContextVar_Type) < 0) ||
+ (PyType_Ready(&PyContextToken_Type) < 0) ||
+ (PyType_Ready(&PyContextTokenMissing_Type) < 0))
+ {
+ return 0;
+ }
+
+ PyObject *missing = get_token_missing();
+ if (PyDict_SetItemString(
+ PyContextToken_Type.tp_dict, "MISSING", missing))
+ {
+ Py_DECREF(missing);
+ return 0;
+ }
+ Py_DECREF(missing);
+
+ return 1;
+}
diff --git a/contrib/tools/python3/src/Python/dtoa.c b/contrib/tools/python3/src/Python/dtoa.c
new file mode 100644
index 00000000000..e629b296426
--- /dev/null
+++ b/contrib/tools/python3/src/Python/dtoa.c
@@ -0,0 +1,2859 @@
+/****************************************************************
+ *
+ * The author of this software is David M. Gay.
+ *
+ * Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ ***************************************************************/
+
+/****************************************************************
+ * This is dtoa.c by David M. Gay, downloaded from
+ * http://www.netlib.org/fp/dtoa.c on April 15, 2009 and modified for
+ * inclusion into the Python core by Mark E. T. Dickinson and Eric V. Smith.
+ *
+ * Please remember to check http://www.netlib.org/fp regularly (and especially
+ * before any Python release) for bugfixes and updates.
+ *
+ * The major modifications from Gay's original code are as follows:
+ *
+ * 0. The original code has been specialized to Python's needs by removing
+ * many of the #ifdef'd sections. In particular, code to support VAX and
+ * IBM floating-point formats, hex NaNs, hex floats, locale-aware
+ * treatment of the decimal point, and setting of the inexact flag have
+ * been removed.
+ *
+ * 1. We use PyMem_Malloc and PyMem_Free in place of malloc and free.
+ *
+ * 2. The public functions strtod, dtoa and freedtoa all now have
+ * a _Py_dg_ prefix.
+ *
+ * 3. Instead of assuming that PyMem_Malloc always succeeds, we thread
+ * PyMem_Malloc failures through the code. The functions
+ *
+ * Balloc, multadd, s2b, i2b, mult, pow5mult, lshift, diff, d2b
+ *
+ * of return type *Bigint all return NULL to indicate a malloc failure.
+ * Similarly, rv_alloc and nrv_alloc (return type char *) return NULL on
+ * failure. bigcomp now has return type int (it used to be void) and
+ * returns -1 on failure and 0 otherwise. _Py_dg_dtoa returns NULL
+ * on failure. _Py_dg_strtod indicates failure due to malloc failure
+ * by returning -1.0, setting errno=ENOMEM and *se to s00.
+ *
+ * 4. The static variable dtoa_result has been removed. Callers of
+ * _Py_dg_dtoa are expected to call _Py_dg_freedtoa to free
+ * the memory allocated by _Py_dg_dtoa.
+ *
+ * 5. The code has been reformatted to better fit with Python's
+ * C style guide (PEP 7).
+ *
+ * 6. A bug in the memory allocation has been fixed: to avoid FREEing memory
+ * that hasn't been MALLOC'ed, private_mem should only be used when k <=
+ * Kmax.
+ *
+ * 7. _Py_dg_strtod has been modified so that it doesn't accept strings with
+ * leading whitespace.
+ *
+ * 8. A corner case where _Py_dg_dtoa didn't strip trailing zeros has been
+ * fixed. (bugs.python.org/issue40780)
+ *
+ ***************************************************************/
+
+/* Please send bug reports for the original dtoa.c code to David M. Gay (dmg
+ * at acm dot org, with " at " changed at "@" and " dot " changed to ".").
+ * Please report bugs for this modified version using the Python issue tracker
+ * (http://bugs.python.org). */
+
+/* On a machine with IEEE extended-precision registers, it is
+ * necessary to specify double-precision (53-bit) rounding precision
+ * before invoking strtod or dtoa. If the machine uses (the equivalent
+ * of) Intel 80x87 arithmetic, the call
+ * _control87(PC_53, MCW_PC);
+ * does this with many compilers. Whether this or another call is
+ * appropriate depends on the compiler; for this to work, it may be
+ * necessary to #include "float.h" or another system-dependent header
+ * file.
+ */
+
+/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
+ *
+ * This strtod returns a nearest machine number to the input decimal
+ * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
+ * broken by the IEEE round-even rule. Otherwise ties are broken by
+ * biased rounding (add half and chop).
+ *
+ * Inspired loosely by William D. Clinger's paper "How to Read Floating
+ * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ *
+ * 1. We only require IEEE, IBM, or VAX double-precision
+ * arithmetic (not IEEE double-extended).
+ * 2. We get by with floating-point arithmetic in a case that
+ * Clinger missed -- when we're computing d * 10^n
+ * for a small integer d and the integer n is not too
+ * much larger than 22 (the maximum integer k for which
+ * we can represent 10^k exactly), we may be able to
+ * compute (d*10^k) * 10^(e-k) with just one roundoff.
+ * 3. Rather than a bit-at-a-time adjustment of the binary
+ * result in the hard case, we use floating-point
+ * arithmetic to determine the adjustment to within
+ * one bit; only in really hard cases do we need to
+ * compute a second residual.
+ * 4. Because of 3., we don't need a large table of powers of 10
+ * for ten-to-e (just some small tables, e.g. of 10^k
+ * for 0 <= k <= 22).
+ */
+
+/* Linking of Python's #defines to Gay's #defines starts here. */
+
+#include "Python.h"
+#include "pycore_dtoa.h"
+
+/* if PY_NO_SHORT_FLOAT_REPR is defined, then don't even try to compile
+ the following code */
+#ifndef PY_NO_SHORT_FLOAT_REPR
+
+#include "float.h"
+
+#define MALLOC PyMem_Malloc
+#define FREE PyMem_Free
+
+/* This code should also work for ARM mixed-endian format on little-endian
+ machines, where doubles have byte order 45670123 (in increasing address
+ order, 0 being the least significant byte). */
+#ifdef DOUBLE_IS_LITTLE_ENDIAN_IEEE754
+# define IEEE_8087
+#endif
+#if defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) || \
+ defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754)
+# define IEEE_MC68k
+#endif
+#if defined(IEEE_8087) + defined(IEEE_MC68k) != 1
+#error "Exactly one of IEEE_8087 or IEEE_MC68k should be defined."
+#endif
+
+/* 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))
+#error "doubles and ints have incompatible endianness"
+#endif
+
+#if !defined(WORDS_BIGENDIAN) && defined(DOUBLE_IS_BIG_ENDIAN_IEEE754)
+#error "doubles and ints have incompatible endianness"
+#endif
+
+
+typedef uint32_t ULong;
+typedef int32_t Long;
+typedef uint64_t ULLong;
+
+#undef DEBUG
+#ifdef Py_DEBUG
+#define DEBUG
+#endif
+
+/* End Python #define linking */
+
+#ifdef DEBUG
+#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
+#endif
+
+#ifndef PRIVATE_MEM
+#define PRIVATE_MEM 2304
+#endif
+#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
+static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef union { double d; ULong L[2]; } U;
+
+#ifdef IEEE_8087
+#define word0(x) (x)->L[1]
+#define word1(x) (x)->L[0]
+#else
+#define word0(x) (x)->L[0]
+#define word1(x) (x)->L[1]
+#endif
+#define dval(x) (x)->d
+
+#ifndef STRTOD_DIGLIM
+#define STRTOD_DIGLIM 40
+#endif
+
+/* maximum permitted exponent value for strtod; exponents larger than
+ MAX_ABS_EXP in absolute value get truncated to +-MAX_ABS_EXP. MAX_ABS_EXP
+ should fit into an int. */
+#ifndef MAX_ABS_EXP
+#define MAX_ABS_EXP 1100000000U
+#endif
+/* Bound on length of pieces of input strings in _Py_dg_strtod; specifically,
+ this is used to bound the total number of digits ignoring leading zeros and
+ the number of digits that follow the decimal point. Ideally, MAX_DIGITS
+ should satisfy MAX_DIGITS + 400 < MAX_ABS_EXP; that ensures that the
+ exponent clipping in _Py_dg_strtod can't affect the value of the output. */
+#ifndef MAX_DIGITS
+#define MAX_DIGITS 1000000000U
+#endif
+
+/* Guard against trying to use the above values on unusual platforms with ints
+ * of width less than 32 bits. */
+#if MAX_ABS_EXP > INT_MAX
+#error "MAX_ABS_EXP should fit in an int"
+#endif
+#if MAX_DIGITS > INT_MAX
+#error "MAX_DIGITS should fit in an int"
+#endif
+
+/* The following definition of Storeinc is appropriate for MIPS processors.
+ * An alternative that might be better on some machines is
+ * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
+ */
+#if defined(IEEE_8087)
+#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
+ ((unsigned short *)a)[0] = (unsigned short)c, a++)
+#else
+#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
+ ((unsigned short *)a)[1] = (unsigned short)c, a++)
+#endif
+
+/* #define P DBL_MANT_DIG */
+/* Ten_pmax = floor(P*log(2)/log(5)) */
+/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
+/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
+/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
+
+#define Exp_shift 20
+#define Exp_shift1 20
+#define Exp_msk1 0x100000
+#define Exp_msk11 0x100000
+#define Exp_mask 0x7ff00000
+#define P 53
+#define Nbits 53
+#define Bias 1023
+#define Emax 1023
+#define Emin (-1022)
+#define Etiny (-1074) /* smallest denormal is 2**Etiny */
+#define Exp_1 0x3ff00000
+#define Exp_11 0x3ff00000
+#define Ebits 11
+#define Frac_mask 0xfffff
+#define Frac_mask1 0xfffff
+#define Ten_pmax 22
+#define Bletch 0x10
+#define Bndry_mask 0xfffff
+#define Bndry_mask1 0xfffff
+#define Sign_bit 0x80000000
+#define Log2P 1
+#define Tiny0 0
+#define Tiny1 1
+#define Quick_max 14
+#define Int_max 14
+
+#ifndef Flt_Rounds
+#ifdef FLT_ROUNDS
+#define Flt_Rounds FLT_ROUNDS
+#else
+#define Flt_Rounds 1
+#endif
+#endif /*Flt_Rounds*/
+
+#define Rounding Flt_Rounds
+
+#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
+#define Big1 0xffffffff
+
+/* Standard NaN used by _Py_dg_stdnan. */
+
+#define NAN_WORD0 0x7ff80000
+#define NAN_WORD1 0
+
+/* Bits of the representation of positive infinity. */
+
+#define POSINF_WORD0 0x7ff00000
+#define POSINF_WORD1 0
+
+/* struct BCinfo is used to pass information from _Py_dg_strtod to bigcomp */
+
+typedef struct BCinfo BCinfo;
+struct
+BCinfo {
+ int e0, nd, nd0, scale;
+};
+
+#define FFFFFFFF 0xffffffffUL
+
+#define Kmax 7
+
+/* struct Bigint is used to represent arbitrary-precision integers. These
+ integers are stored in sign-magnitude format, with the magnitude stored as
+ an array of base 2**32 digits. Bigints are always normalized: if x is a
+ Bigint then x->wds >= 1, and either x->wds == 1 or x[wds-1] is nonzero.
+
+ The Bigint fields are as follows:
+
+ - next is a header used by Balloc and Bfree to keep track of lists
+ of freed Bigints; it's also used for the linked list of
+ powers of 5 of the form 5**2**i used by pow5mult.
+ - k indicates which pool this Bigint was allocated from
+ - maxwds is the maximum number of words space was allocated for
+ (usually maxwds == 2**k)
+ - sign is 1 for negative Bigints, 0 for positive. The sign is unused
+ (ignored on inputs, set to 0 on outputs) in almost all operations
+ involving Bigints: a notable exception is the diff function, which
+ ignores signs on inputs but sets the sign of the output correctly.
+ - wds is the actual number of significant words
+ - x contains the vector of words (digits) for this Bigint, from least
+ significant (x[0]) to most significant (x[wds-1]).
+*/
+
+struct
+Bigint {
+ struct Bigint *next;
+ int k, maxwds, sign, wds;
+ ULong x[1];
+};
+
+typedef struct Bigint Bigint;
+
+#ifndef Py_USING_MEMORY_DEBUGGER
+
+/* Memory management: memory is allocated from, and returned to, Kmax+1 pools
+ of memory, where pool k (0 <= k <= Kmax) is for Bigints b with b->maxwds ==
+ 1 << k. These pools are maintained as linked lists, with freelist[k]
+ pointing to the head of the list for pool k.
+
+ On allocation, if there's no free slot in the appropriate pool, MALLOC is
+ called to get more memory. This memory is not returned to the system until
+ Python quits. There's also a private memory pool that's allocated from
+ in preference to using MALLOC.
+
+ For Bigints with more than (1 << Kmax) digits (which implies at least 1233
+ decimal digits), memory is directly allocated using MALLOC, and freed using
+ FREE.
+
+ XXX: it would be easy to bypass this memory-management system and
+ translate each call to Balloc into a call to PyMem_Malloc, and each
+ Bfree to PyMem_Free. Investigate whether this has any significant
+ performance on impact. */
+
+static Bigint *freelist[Kmax+1];
+
+/* Allocate space for a Bigint with up to 1<<k digits */
+
+static Bigint *
+Balloc(int k)
+{
+ int x;
+ Bigint *rv;
+ unsigned int len;
+
+ if (k <= Kmax && (rv = freelist[k]))
+ freelist[k] = rv->next;
+ else {
+ x = 1 << k;
+ len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
+ /sizeof(double);
+ if (k <= Kmax && pmem_next - private_mem + len <= (Py_ssize_t)PRIVATE_mem) {
+ rv = (Bigint*)pmem_next;
+ pmem_next += len;
+ }
+ else {
+ rv = (Bigint*)MALLOC(len*sizeof(double));
+ if (rv == NULL)
+ return NULL;
+ }
+ rv->k = k;
+ rv->maxwds = x;
+ }
+ rv->sign = rv->wds = 0;
+ return rv;
+}
+
+/* Free a Bigint allocated with Balloc */
+
+static void
+Bfree(Bigint *v)
+{
+ if (v) {
+ if (v->k > Kmax)
+ FREE((void*)v);
+ else {
+ v->next = freelist[v->k];
+ freelist[v->k] = v;
+ }
+ }
+}
+
+#else
+
+/* Alternative versions of Balloc and Bfree that use PyMem_Malloc and
+ PyMem_Free directly in place of the custom memory allocation scheme above.
+ These are provided for the benefit of memory debugging tools like
+ Valgrind. */
+
+/* Allocate space for a Bigint with up to 1<<k digits */
+
+static Bigint *
+Balloc(int k)
+{
+ int x;
+ Bigint *rv;
+ unsigned int len;
+
+ x = 1 << k;
+ len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
+ /sizeof(double);
+
+ rv = (Bigint*)MALLOC(len*sizeof(double));
+ if (rv == NULL)
+ return NULL;
+
+ rv->k = k;
+ rv->maxwds = x;
+ rv->sign = rv->wds = 0;
+ return rv;
+}
+
+/* Free a Bigint allocated with Balloc */
+
+static void
+Bfree(Bigint *v)
+{
+ if (v) {
+ FREE((void*)v);
+ }
+}
+
+#endif /* Py_USING_MEMORY_DEBUGGER */
+
+#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
+ y->wds*sizeof(Long) + 2*sizeof(int))
+
+/* Multiply a Bigint b by m and add a. Either modifies b in place and returns
+ a pointer to the modified b, or Bfrees b and returns a pointer to a copy.
+ On failure, return NULL. In this case, b will have been already freed. */
+
+static Bigint *
+multadd(Bigint *b, int m, int a) /* multiply by m and add a */
+{
+ int i, wds;
+ ULong *x;
+ ULLong carry, y;
+ Bigint *b1;
+
+ wds = b->wds;
+ x = b->x;
+ i = 0;
+ carry = a;
+ do {
+ y = *x * (ULLong)m + carry;
+ carry = y >> 32;
+ *x++ = (ULong)(y & FFFFFFFF);
+ }
+ while(++i < wds);
+ if (carry) {
+ if (wds >= b->maxwds) {
+ b1 = Balloc(b->k+1);
+ if (b1 == NULL){
+ Bfree(b);
+ return NULL;
+ }
+ Bcopy(b1, b);
+ Bfree(b);
+ b = b1;
+ }
+ b->x[wds++] = (ULong)carry;
+ b->wds = wds;
+ }
+ return b;
+}
+
+/* convert a string s containing nd decimal digits (possibly containing a
+ decimal separator at position nd0, which is ignored) to a Bigint. This
+ function carries on where the parsing code in _Py_dg_strtod leaves off: on
+ entry, y9 contains the result of converting the first 9 digits. Returns
+ NULL on failure. */
+
+static Bigint *
+s2b(const char *s, int nd0, int nd, ULong y9)
+{
+ Bigint *b;
+ int i, k;
+ Long x, y;
+
+ x = (nd + 8) / 9;
+ for(k = 0, y = 1; x > y; y <<= 1, k++) ;
+ b = Balloc(k);
+ if (b == NULL)
+ return NULL;
+ b->x[0] = y9;
+ b->wds = 1;
+
+ if (nd <= 9)
+ return b;
+
+ s += 9;
+ for (i = 9; i < nd0; i++) {
+ b = multadd(b, 10, *s++ - '0');
+ if (b == NULL)
+ return NULL;
+ }
+ s++;
+ for(; i < nd; i++) {
+ b = multadd(b, 10, *s++ - '0');
+ if (b == NULL)
+ return NULL;
+ }
+ return b;
+}
+
+/* count leading 0 bits in the 32-bit integer x. */
+
+static int
+hi0bits(ULong x)
+{
+ int k = 0;
+
+ if (!(x & 0xffff0000)) {
+ k = 16;
+ x <<= 16;
+ }
+ if (!(x & 0xff000000)) {
+ k += 8;
+ x <<= 8;
+ }
+ if (!(x & 0xf0000000)) {
+ k += 4;
+ x <<= 4;
+ }
+ if (!(x & 0xc0000000)) {
+ k += 2;
+ x <<= 2;
+ }
+ if (!(x & 0x80000000)) {
+ k++;
+ if (!(x & 0x40000000))
+ return 32;
+ }
+ return k;
+}
+
+/* count trailing 0 bits in the 32-bit integer y, and shift y right by that
+ number of bits. */
+
+static int
+lo0bits(ULong *y)
+{
+ int k;
+ ULong x = *y;
+
+ if (x & 7) {
+ if (x & 1)
+ return 0;
+ if (x & 2) {
+ *y = x >> 1;
+ return 1;
+ }
+ *y = x >> 2;
+ return 2;
+ }
+ k = 0;
+ if (!(x & 0xffff)) {
+ k = 16;
+ x >>= 16;
+ }
+ if (!(x & 0xff)) {
+ k += 8;
+ x >>= 8;
+ }
+ if (!(x & 0xf)) {
+ k += 4;
+ x >>= 4;
+ }
+ if (!(x & 0x3)) {
+ k += 2;
+ x >>= 2;
+ }
+ if (!(x & 1)) {
+ k++;
+ x >>= 1;
+ if (!x)
+ return 32;
+ }
+ *y = x;
+ return k;
+}
+
+/* convert a small nonnegative integer to a Bigint */
+
+static Bigint *
+i2b(int i)
+{
+ Bigint *b;
+
+ b = Balloc(1);
+ if (b == NULL)
+ return NULL;
+ b->x[0] = i;
+ b->wds = 1;
+ return b;
+}
+
+/* multiply two Bigints. Returns a new Bigint, or NULL on failure. Ignores
+ the signs of a and b. */
+
+static Bigint *
+mult(Bigint *a, Bigint *b)
+{
+ Bigint *c;
+ int k, wa, wb, wc;
+ ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
+ ULong y;
+ ULLong carry, z;
+
+ if ((!a->x[0] && a->wds == 1) || (!b->x[0] && b->wds == 1)) {
+ c = Balloc(0);
+ if (c == NULL)
+ return NULL;
+ c->wds = 1;
+ c->x[0] = 0;
+ return c;
+ }
+
+ if (a->wds < b->wds) {
+ c = a;
+ a = b;
+ b = c;
+ }
+ k = a->k;
+ wa = a->wds;
+ wb = b->wds;
+ wc = wa + wb;
+ if (wc > a->maxwds)
+ k++;
+ c = Balloc(k);
+ if (c == NULL)
+ return NULL;
+ for(x = c->x, xa = x + wc; x < xa; x++)
+ *x = 0;
+ xa = a->x;
+ xae = xa + wa;
+ xb = b->x;
+ xbe = xb + wb;
+ xc0 = c->x;
+ for(; xb < xbe; xc0++) {
+ if ((y = *xb++)) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = *x++ * (ULLong)y + *xc + carry;
+ carry = z >> 32;
+ *xc++ = (ULong)(z & FFFFFFFF);
+ }
+ while(x < xae);
+ *xc = (ULong)carry;
+ }
+ }
+ for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
+ c->wds = wc;
+ return c;
+}
+
+#ifndef Py_USING_MEMORY_DEBUGGER
+
+/* p5s is a linked list of powers of 5 of the form 5**(2**i), i >= 2 */
+
+static Bigint *p5s;
+
+/* multiply the Bigint b by 5**k. Returns a pointer to the result, or NULL on
+ failure; if the returned pointer is distinct from b then the original
+ Bigint b will have been Bfree'd. Ignores the sign of b. */
+
+static Bigint *
+pow5mult(Bigint *b, int k)
+{
+ Bigint *b1, *p5, *p51;
+ int i;
+ static const int p05[3] = { 5, 25, 125 };
+
+ if ((i = k & 3)) {
+ b = multadd(b, p05[i-1], 0);
+ if (b == NULL)
+ return NULL;
+ }
+
+ if (!(k >>= 2))
+ return b;
+ p5 = p5s;
+ if (!p5) {
+ /* first time */
+ p5 = i2b(625);
+ if (p5 == NULL) {
+ Bfree(b);
+ return NULL;
+ }
+ p5s = p5;
+ p5->next = 0;
+ }
+ for(;;) {
+ if (k & 1) {
+ b1 = mult(b, p5);
+ Bfree(b);
+ b = b1;
+ if (b == NULL)
+ return NULL;
+ }
+ if (!(k >>= 1))
+ break;
+ p51 = p5->next;
+ if (!p51) {
+ p51 = mult(p5,p5);
+ if (p51 == NULL) {
+ Bfree(b);
+ return NULL;
+ }
+ p51->next = 0;
+ p5->next = p51;
+ }
+ p5 = p51;
+ }
+ return b;
+}
+
+#else
+
+/* Version of pow5mult that doesn't cache powers of 5. Provided for
+ the benefit of memory debugging tools like Valgrind. */
+
+static Bigint *
+pow5mult(Bigint *b, int k)
+{
+ Bigint *b1, *p5, *p51;
+ int i;
+ static const int p05[3] = { 5, 25, 125 };
+
+ if ((i = k & 3)) {
+ b = multadd(b, p05[i-1], 0);
+ if (b == NULL)
+ return NULL;
+ }
+
+ if (!(k >>= 2))
+ return b;
+ p5 = i2b(625);
+ if (p5 == NULL) {
+ Bfree(b);
+ return NULL;
+ }
+
+ for(;;) {
+ if (k & 1) {
+ b1 = mult(b, p5);
+ Bfree(b);
+ b = b1;
+ if (b == NULL) {
+ Bfree(p5);
+ return NULL;
+ }
+ }
+ if (!(k >>= 1))
+ break;
+ p51 = mult(p5, p5);
+ Bfree(p5);
+ p5 = p51;
+ if (p5 == NULL) {
+ Bfree(b);
+ return NULL;
+ }
+ }
+ Bfree(p5);
+ return b;
+}
+
+#endif /* Py_USING_MEMORY_DEBUGGER */
+
+/* shift a Bigint b left by k bits. Return a pointer to the shifted result,
+ or NULL on failure. If the returned pointer is distinct from b then the
+ original b will have been Bfree'd. Ignores the sign of b. */
+
+static Bigint *
+lshift(Bigint *b, int k)
+{
+ int i, k1, n, n1;
+ Bigint *b1;
+ ULong *x, *x1, *xe, z;
+
+ if (!k || (!b->x[0] && b->wds == 1))
+ return b;
+
+ n = k >> 5;
+ k1 = b->k;
+ n1 = n + b->wds + 1;
+ for(i = b->maxwds; n1 > i; i <<= 1)
+ k1++;
+ b1 = Balloc(k1);
+ if (b1 == NULL) {
+ Bfree(b);
+ return NULL;
+ }
+ x1 = b1->x;
+ for(i = 0; i < n; i++)
+ *x1++ = 0;
+ x = b->x;
+ xe = x + b->wds;
+ if (k &= 0x1f) {
+ k1 = 32 - k;
+ z = 0;
+ do {
+ *x1++ = *x << k | z;
+ z = *x++ >> k1;
+ }
+ while(x < xe);
+ if ((*x1 = z))
+ ++n1;
+ }
+ else do
+ *x1++ = *x++;
+ while(x < xe);
+ b1->wds = n1 - 1;
+ Bfree(b);
+ return b1;
+}
+
+/* Do a three-way compare of a and b, returning -1 if a < b, 0 if a == b and
+ 1 if a > b. Ignores signs of a and b. */
+
+static int
+cmp(Bigint *a, Bigint *b)
+{
+ ULong *xa, *xa0, *xb, *xb0;
+ int i, j;
+
+ i = a->wds;
+ j = b->wds;
+#ifdef DEBUG
+ if (i > 1 && !a->x[i-1])
+ Bug("cmp called with a->x[a->wds-1] == 0");
+ if (j > 1 && !b->x[j-1])
+ Bug("cmp called with b->x[b->wds-1] == 0");
+#endif
+ if (i -= j)
+ return i;
+ xa0 = a->x;
+ xa = xa0 + j;
+ xb0 = b->x;
+ xb = xb0 + j;
+ for(;;) {
+ if (*--xa != *--xb)
+ return *xa < *xb ? -1 : 1;
+ if (xa <= xa0)
+ break;
+ }
+ return 0;
+}
+
+/* Take the difference of Bigints a and b, returning a new Bigint. Returns
+ NULL on failure. The signs of a and b are ignored, but the sign of the
+ result is set appropriately. */
+
+static Bigint *
+diff(Bigint *a, Bigint *b)
+{
+ Bigint *c;
+ int i, wa, wb;
+ ULong *xa, *xae, *xb, *xbe, *xc;
+ ULLong borrow, y;
+
+ i = cmp(a,b);
+ if (!i) {
+ c = Balloc(0);
+ if (c == NULL)
+ return NULL;
+ c->wds = 1;
+ c->x[0] = 0;
+ return c;
+ }
+ if (i < 0) {
+ c = a;
+ a = b;
+ b = c;
+ i = 1;
+ }
+ else
+ i = 0;
+ c = Balloc(a->k);
+ if (c == NULL)
+ return NULL;
+ c->sign = i;
+ wa = a->wds;
+ xa = a->x;
+ xae = xa + wa;
+ wb = b->wds;
+ xb = b->x;
+ xbe = xb + wb;
+ xc = c->x;
+ borrow = 0;
+ do {
+ y = (ULLong)*xa++ - *xb++ - borrow;
+ borrow = y >> 32 & (ULong)1;
+ *xc++ = (ULong)(y & FFFFFFFF);
+ }
+ while(xb < xbe);
+ while(xa < xae) {
+ y = *xa++ - borrow;
+ borrow = y >> 32 & (ULong)1;
+ *xc++ = (ULong)(y & FFFFFFFF);
+ }
+ while(!*--xc)
+ wa--;
+ c->wds = wa;
+ return c;
+}
+
+/* Given a positive normal double x, return the difference between x and the
+ next double up. Doesn't give correct results for subnormals. */
+
+static double
+ulp(U *x)
+{
+ Long L;
+ U u;
+
+ L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
+ word0(&u) = L;
+ word1(&u) = 0;
+ return dval(&u);
+}
+
+/* Convert a Bigint to a double plus an exponent */
+
+static double
+b2d(Bigint *a, int *e)
+{
+ ULong *xa, *xa0, w, y, z;
+ int k;
+ U d;
+
+ xa0 = a->x;
+ xa = xa0 + a->wds;
+ y = *--xa;
+#ifdef DEBUG
+ if (!y) Bug("zero y in b2d");
+#endif
+ k = hi0bits(y);
+ *e = 32 - k;
+ if (k < Ebits) {
+ word0(&d) = Exp_1 | y >> (Ebits - k);
+ w = xa > xa0 ? *--xa : 0;
+ word1(&d) = y << ((32-Ebits) + k) | w >> (Ebits - k);
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ if (k -= Ebits) {
+ word0(&d) = Exp_1 | y << k | z >> (32 - k);
+ y = xa > xa0 ? *--xa : 0;
+ word1(&d) = z << k | y >> (32 - k);
+ }
+ else {
+ word0(&d) = Exp_1 | y;
+ word1(&d) = z;
+ }
+ ret_d:
+ return dval(&d);
+}
+
+/* Convert a scaled double to a Bigint plus an exponent. Similar to d2b,
+ except that it accepts the scale parameter used in _Py_dg_strtod (which
+ should be either 0 or 2*P), and the normalization for the return value is
+ different (see below). On input, d should be finite and nonnegative, and d
+ / 2**scale should be exactly representable as an IEEE 754 double.
+
+ Returns a Bigint b and an integer e such that
+
+ dval(d) / 2**scale = b * 2**e.
+
+ Unlike d2b, b is not necessarily odd: b and e are normalized so
+ that either 2**(P-1) <= b < 2**P and e >= Etiny, or b < 2**P
+ and e == Etiny. This applies equally to an input of 0.0: in that
+ case the return values are b = 0 and e = Etiny.
+
+ The above normalization ensures that for all possible inputs d,
+ 2**e gives ulp(d/2**scale).
+
+ Returns NULL on failure.
+*/
+
+static Bigint *
+sd2b(U *d, int scale, int *e)
+{
+ Bigint *b;
+
+ b = Balloc(1);
+ if (b == NULL)
+ return NULL;
+
+ /* First construct b and e assuming that scale == 0. */
+ b->wds = 2;
+ b->x[0] = word1(d);
+ b->x[1] = word0(d) & Frac_mask;
+ *e = Etiny - 1 + (int)((word0(d) & Exp_mask) >> Exp_shift);
+ if (*e < Etiny)
+ *e = Etiny;
+ else
+ b->x[1] |= Exp_msk1;
+
+ /* Now adjust for scale, provided that b != 0. */
+ if (scale && (b->x[0] || b->x[1])) {
+ *e -= scale;
+ if (*e < Etiny) {
+ scale = Etiny - *e;
+ *e = Etiny;
+ /* We can't shift more than P-1 bits without shifting out a 1. */
+ assert(0 < scale && scale <= P - 1);
+ if (scale >= 32) {
+ /* The bits shifted out should all be zero. */
+ assert(b->x[0] == 0);
+ b->x[0] = b->x[1];
+ b->x[1] = 0;
+ scale -= 32;
+ }
+ if (scale) {
+ /* The bits shifted out should all be zero. */
+ assert(b->x[0] << (32 - scale) == 0);
+ b->x[0] = (b->x[0] >> scale) | (b->x[1] << (32 - scale));
+ b->x[1] >>= scale;
+ }
+ }
+ }
+ /* Ensure b is normalized. */
+ if (!b->x[1])
+ b->wds = 1;
+
+ return b;
+}
+
+/* Convert a double to a Bigint plus an exponent. Return NULL on failure.
+
+ Given a finite nonzero double d, return an odd Bigint b and exponent *e
+ such that fabs(d) = b * 2**e. On return, *bbits gives the number of
+ significant bits of b; that is, 2**(*bbits-1) <= b < 2**(*bbits).
+
+ If d is zero, then b == 0, *e == -1010, *bbits = 0.
+ */
+
+static Bigint *
+d2b(U *d, int *e, int *bits)
+{
+ Bigint *b;
+ int de, k;
+ ULong *x, y, z;
+ int i;
+
+ b = Balloc(1);
+ if (b == NULL)
+ return NULL;
+ x = b->x;
+
+ z = word0(d) & Frac_mask;
+ word0(d) &= 0x7fffffff; /* clear sign bit, which we ignore */
+ if ((de = (int)(word0(d) >> Exp_shift)))
+ z |= Exp_msk1;
+ if ((y = word1(d))) {
+ if ((k = lo0bits(&y))) {
+ x[0] = y | z << (32 - k);
+ z >>= k;
+ }
+ else
+ x[0] = y;
+ i =
+ b->wds = (x[1] = z) ? 2 : 1;
+ }
+ else {
+ k = lo0bits(&z);
+ x[0] = z;
+ i =
+ b->wds = 1;
+ k += 32;
+ }
+ if (de) {
+ *e = de - Bias - (P-1) + k;
+ *bits = P - k;
+ }
+ else {
+ *e = de - Bias - (P-1) + 1 + k;
+ *bits = 32*i - hi0bits(x[i-1]);
+ }
+ return b;
+}
+
+/* Compute the ratio of two Bigints, as a double. The result may have an
+ error of up to 2.5 ulps. */
+
+static double
+ratio(Bigint *a, Bigint *b)
+{
+ U da, db;
+ int k, ka, kb;
+
+ dval(&da) = b2d(a, &ka);
+ dval(&db) = b2d(b, &kb);
+ k = ka - kb + 32*(a->wds - b->wds);
+ if (k > 0)
+ word0(&da) += k*Exp_msk1;
+ else {
+ k = -k;
+ word0(&db) += k*Exp_msk1;
+ }
+ return dval(&da) / dval(&db);
+}
+
+static const double
+tens[] = {
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+ 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+ 1e20, 1e21, 1e22
+};
+
+static const double
+bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
+static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
+ 9007199254740992.*9007199254740992.e-256
+ /* = 2^106 * 1e-256 */
+};
+/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */
+/* flag unnecessarily. It leads to a song and dance at the end of strtod. */
+#define Scale_Bit 0x10
+#define n_bigtens 5
+
+#define ULbits 32
+#define kshift 5
+#define kmask 31
+
+
+static int
+dshift(Bigint *b, int p2)
+{
+ int rv = hi0bits(b->x[b->wds-1]) - 4;
+ if (p2 > 0)
+ rv -= p2;
+ return rv & kmask;
+}
+
+/* special case of Bigint division. The quotient is always in the range 0 <=
+ quotient < 10, and on entry the divisor S is normalized so that its top 4
+ bits (28--31) are zero and bit 27 is set. */
+
+static int
+quorem(Bigint *b, Bigint *S)
+{
+ int n;
+ ULong *bx, *bxe, q, *sx, *sxe;
+ ULLong borrow, carry, y, ys;
+
+ n = S->wds;
+#ifdef DEBUG
+ /*debug*/ if (b->wds > n)
+ /*debug*/ Bug("oversize b in quorem");
+#endif
+ if (b->wds < n)
+ return 0;
+ sx = S->x;
+ sxe = sx + --n;
+ bx = b->x;
+ bxe = bx + n;
+ q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
+#ifdef DEBUG
+ /*debug*/ if (q > 9)
+ /*debug*/ Bug("oversized quotient in quorem");
+#endif
+ if (q) {
+ borrow = 0;
+ carry = 0;
+ do {
+ ys = *sx++ * (ULLong)q + carry;
+ carry = ys >> 32;
+ y = *bx - (ys & FFFFFFFF) - borrow;
+ borrow = y >> 32 & (ULong)1;
+ *bx++ = (ULong)(y & FFFFFFFF);
+ }
+ while(sx <= sxe);
+ if (!*bxe) {
+ bx = b->x;
+ while(--bxe > bx && !*bxe)
+ --n;
+ b->wds = n;
+ }
+ }
+ if (cmp(b, S) >= 0) {
+ q++;
+ borrow = 0;
+ carry = 0;
+ bx = b->x;
+ sx = S->x;
+ do {
+ ys = *sx++ + carry;
+ carry = ys >> 32;
+ y = *bx - (ys & FFFFFFFF) - borrow;
+ borrow = y >> 32 & (ULong)1;
+ *bx++ = (ULong)(y & FFFFFFFF);
+ }
+ while(sx <= sxe);
+ bx = b->x;
+ bxe = bx + n;
+ if (!*bxe) {
+ while(--bxe > bx && !*bxe)
+ --n;
+ b->wds = n;
+ }
+ }
+ return q;
+}
+
+/* sulp(x) is a version of ulp(x) that takes bc.scale into account.
+
+ Assuming that x is finite and nonnegative (positive zero is fine
+ here) and x / 2^bc.scale is exactly representable as a double,
+ sulp(x) is equivalent to 2^bc.scale * ulp(x / 2^bc.scale). */
+
+static double
+sulp(U *x, BCinfo *bc)
+{
+ U u;
+
+ if (bc->scale && 2*P + 1 > (int)((word0(x) & Exp_mask) >> Exp_shift)) {
+ /* rv/2^bc->scale is subnormal */
+ word0(&u) = (P+2)*Exp_msk1;
+ word1(&u) = 0;
+ return u.d;
+ }
+ else {
+ assert(word0(x) || word1(x)); /* x != 0.0 */
+ return ulp(x);
+ }
+}
+
+/* The bigcomp function handles some hard cases for strtod, for inputs
+ with more than STRTOD_DIGLIM digits. It's called once an initial
+ estimate for the double corresponding to the input string has
+ already been obtained by the code in _Py_dg_strtod.
+
+ The bigcomp function is only called after _Py_dg_strtod has found a
+ double value rv such that either rv or rv + 1ulp represents the
+ correctly rounded value corresponding to the original string. It
+ determines which of these two values is the correct one by
+ computing the decimal digits of rv + 0.5ulp and comparing them with
+ the corresponding digits of s0.
+
+ In the following, write dv for the absolute value of the number represented
+ by the input string.
+
+ Inputs:
+
+ s0 points to the first significant digit of the input string.
+
+ rv is a (possibly scaled) estimate for the closest double value to the
+ value represented by the original input to _Py_dg_strtod. If
+ bc->scale is nonzero, then rv/2^(bc->scale) is the approximation to
+ the input value.
+
+ bc is a struct containing information gathered during the parsing and
+ estimation steps of _Py_dg_strtod. Description of fields follows:
+
+ bc->e0 gives the exponent of the input value, such that dv = (integer
+ given by the bd->nd digits of s0) * 10**e0
+
+ bc->nd gives the total number of significant digits of s0. It will
+ be at least 1.
+
+ bc->nd0 gives the number of significant digits of s0 before the
+ decimal separator. If there's no decimal separator, bc->nd0 ==
+ bc->nd.
+
+ bc->scale is the value used to scale rv to avoid doing arithmetic with
+ subnormal values. It's either 0 or 2*P (=106).
+
+ Outputs:
+
+ On successful exit, rv/2^(bc->scale) is the closest double to dv.
+
+ Returns 0 on success, -1 on failure (e.g., due to a failed malloc call). */
+
+static int
+bigcomp(U *rv, const char *s0, BCinfo *bc)
+{
+ Bigint *b, *d;
+ int b2, d2, dd, i, nd, nd0, odd, p2, p5;
+
+ nd = bc->nd;
+ nd0 = bc->nd0;
+ p5 = nd + bc->e0;
+ b = sd2b(rv, bc->scale, &p2);
+ if (b == NULL)
+ return -1;
+
+ /* record whether the lsb of rv/2^(bc->scale) is odd: in the exact halfway
+ case, this is used for round to even. */
+ odd = b->x[0] & 1;
+
+ /* left shift b by 1 bit and or a 1 into the least significant bit;
+ this gives us b * 2**p2 = rv/2^(bc->scale) + 0.5 ulp. */
+ b = lshift(b, 1);
+ if (b == NULL)
+ return -1;
+ b->x[0] |= 1;
+ p2--;
+
+ p2 -= p5;
+ d = i2b(1);
+ if (d == NULL) {
+ Bfree(b);
+ return -1;
+ }
+ /* Arrange for convenient computation of quotients:
+ * shift left if necessary so divisor has 4 leading 0 bits.
+ */
+ if (p5 > 0) {
+ d = pow5mult(d, p5);
+ if (d == NULL) {
+ Bfree(b);
+ return -1;
+ }
+ }
+ else if (p5 < 0) {
+ b = pow5mult(b, -p5);
+ if (b == NULL) {
+ Bfree(d);
+ return -1;
+ }
+ }
+ if (p2 > 0) {
+ b2 = p2;
+ d2 = 0;
+ }
+ else {
+ b2 = 0;
+ d2 = -p2;
+ }
+ i = dshift(d, d2);
+ if ((b2 += i) > 0) {
+ b = lshift(b, b2);
+ if (b == NULL) {
+ Bfree(d);
+ return -1;
+ }
+ }
+ if ((d2 += i) > 0) {
+ d = lshift(d, d2);
+ if (d == NULL) {
+ Bfree(b);
+ return -1;
+ }
+ }
+
+ /* Compare s0 with b/d: set dd to -1, 0, or 1 according as s0 < b/d, s0 ==
+ * b/d, or s0 > b/d. Here the digits of s0 are thought of as representing
+ * a number in the range [0.1, 1). */
+ if (cmp(b, d) >= 0)
+ /* b/d >= 1 */
+ dd = -1;
+ else {
+ i = 0;
+ for(;;) {
+ b = multadd(b, 10, 0);
+ if (b == NULL) {
+ Bfree(d);
+ return -1;
+ }
+ dd = s0[i < nd0 ? i : i+1] - '0' - quorem(b, d);
+ i++;
+
+ if (dd)
+ break;
+ if (!b->x[0] && b->wds == 1) {
+ /* b/d == 0 */
+ dd = i < nd;
+ break;
+ }
+ if (!(i < nd)) {
+ /* b/d != 0, but digits of s0 exhausted */
+ dd = -1;
+ break;
+ }
+ }
+ }
+ Bfree(b);
+ Bfree(d);
+ if (dd > 0 || (dd == 0 && odd))
+ dval(rv) += sulp(rv, bc);
+ return 0;
+}
+
+/* Return a 'standard' NaN value.
+
+ There are exactly two quiet NaNs that don't arise by 'quieting' signaling
+ NaNs (see IEEE 754-2008, section 6.2.1). If sign == 0, return the one whose
+ sign bit is cleared. Otherwise, return the one whose sign bit is set.
+*/
+
+double
+_Py_dg_stdnan(int sign)
+{
+ U rv;
+ word0(&rv) = NAN_WORD0;
+ word1(&rv) = NAN_WORD1;
+ if (sign)
+ word0(&rv) |= Sign_bit;
+ return dval(&rv);
+}
+
+/* Return positive or negative infinity, according to the given sign (0 for
+ * positive infinity, 1 for negative infinity). */
+
+double
+_Py_dg_infinity(int sign)
+{
+ U rv;
+ word0(&rv) = POSINF_WORD0;
+ word1(&rv) = POSINF_WORD1;
+ return sign ? -dval(&rv) : dval(&rv);
+}
+
+double
+_Py_dg_strtod(const char *s00, char **se)
+{
+ int bb2, bb5, bbe, bd2, bd5, bs2, c, dsign, e, e1, error;
+ int esign, i, j, k, lz, nd, nd0, odd, sign;
+ const char *s, *s0, *s1;
+ double aadj, aadj1;
+ U aadj2, adj, rv, rv0;
+ ULong y, z, abs_exp;
+ Long L;
+ BCinfo bc;
+ Bigint *bb = NULL, *bd = NULL, *bd0 = NULL, *bs = NULL, *delta = NULL;
+ size_t ndigits, fraclen;
+ double result;
+
+ dval(&rv) = 0.;
+
+ /* Start parsing. */
+ c = *(s = s00);
+
+ /* Parse optional sign, if present. */
+ sign = 0;
+ switch (c) {
+ case '-':
+ sign = 1;
+ /* fall through */
+ case '+':
+ c = *++s;
+ }
+
+ /* Skip leading zeros: lz is true iff there were leading zeros. */
+ s1 = s;
+ while (c == '0')
+ c = *++s;
+ lz = s != s1;
+
+ /* Point s0 at the first nonzero digit (if any). fraclen will be the
+ number of digits between the decimal point and the end of the
+ digit string. ndigits will be the total number of digits ignoring
+ leading zeros. */
+ s0 = s1 = s;
+ while ('0' <= c && c <= '9')
+ c = *++s;
+ ndigits = s - s1;
+ fraclen = 0;
+
+ /* Parse decimal point and following digits. */
+ if (c == '.') {
+ c = *++s;
+ if (!ndigits) {
+ s1 = s;
+ while (c == '0')
+ c = *++s;
+ lz = lz || s != s1;
+ fraclen += (s - s1);
+ s0 = s;
+ }
+ s1 = s;
+ while ('0' <= c && c <= '9')
+ c = *++s;
+ ndigits += s - s1;
+ fraclen += s - s1;
+ }
+
+ /* Now lz is true if and only if there were leading zero digits, and
+ ndigits gives the total number of digits ignoring leading zeros. A
+ valid input must have at least one digit. */
+ if (!ndigits && !lz) {
+ if (se)
+ *se = (char *)s00;
+ goto parse_error;
+ }
+
+ /* Range check ndigits and fraclen to make sure that they, and values
+ computed with them, can safely fit in an int. */
+ if (ndigits > MAX_DIGITS || fraclen > MAX_DIGITS) {
+ if (se)
+ *se = (char *)s00;
+ goto parse_error;
+ }
+ nd = (int)ndigits;
+ nd0 = (int)ndigits - (int)fraclen;
+
+ /* Parse exponent. */
+ e = 0;
+ if (c == 'e' || c == 'E') {
+ s00 = s;
+ c = *++s;
+
+ /* Exponent sign. */
+ esign = 0;
+ switch (c) {
+ case '-':
+ esign = 1;
+ /* fall through */
+ case '+':
+ c = *++s;
+ }
+
+ /* Skip zeros. lz is true iff there are leading zeros. */
+ s1 = s;
+ while (c == '0')
+ c = *++s;
+ lz = s != s1;
+
+ /* Get absolute value of the exponent. */
+ s1 = s;
+ abs_exp = 0;
+ while ('0' <= c && c <= '9') {
+ abs_exp = 10*abs_exp + (c - '0');
+ c = *++s;
+ }
+
+ /* abs_exp will be correct modulo 2**32. But 10**9 < 2**32, so if
+ there are at most 9 significant exponent digits then overflow is
+ impossible. */
+ if (s - s1 > 9 || abs_exp > MAX_ABS_EXP)
+ e = (int)MAX_ABS_EXP;
+ else
+ e = (int)abs_exp;
+ if (esign)
+ e = -e;
+
+ /* A valid exponent must have at least one digit. */
+ if (s == s1 && !lz)
+ s = s00;
+ }
+
+ /* Adjust exponent to take into account position of the point. */
+ e -= nd - nd0;
+ if (nd0 <= 0)
+ nd0 = nd;
+
+ /* Finished parsing. Set se to indicate how far we parsed */
+ if (se)
+ *se = (char *)s;
+
+ /* If all digits were zero, exit with return value +-0.0. Otherwise,
+ strip trailing zeros: scan back until we hit a nonzero digit. */
+ if (!nd)
+ goto ret;
+ for (i = nd; i > 0; ) {
+ --i;
+ if (s0[i < nd0 ? i : i+1] != '0') {
+ ++i;
+ break;
+ }
+ }
+ e += nd - i;
+ nd = i;
+ if (nd0 > nd)
+ nd0 = nd;
+
+ /* Summary of parsing results. After parsing, and dealing with zero
+ * inputs, we have values s0, nd0, nd, e, sign, where:
+ *
+ * - s0 points to the first significant digit of the input string
+ *
+ * - nd is the total number of significant digits (here, and
+ * below, 'significant digits' means the set of digits of the
+ * significand of the input that remain after ignoring leading
+ * and trailing zeros).
+ *
+ * - nd0 indicates the position of the decimal point, if present; it
+ * satisfies 1 <= nd0 <= nd. The nd significant digits are in
+ * s0[0:nd0] and s0[nd0+1:nd+1] using the usual Python half-open slice
+ * notation. (If nd0 < nd, then s0[nd0] contains a '.' character; if
+ * nd0 == nd, then s0[nd0] could be any non-digit character.)
+ *
+ * - e is the adjusted exponent: the absolute value of the number
+ * represented by the original input string is n * 10**e, where
+ * n is the integer represented by the concatenation of
+ * s0[0:nd0] and s0[nd0+1:nd+1]
+ *
+ * - sign gives the sign of the input: 1 for negative, 0 for positive
+ *
+ * - the first and last significant digits are nonzero
+ */
+
+ /* put first DBL_DIG+1 digits into integer y and z.
+ *
+ * - y contains the value represented by the first min(9, nd)
+ * significant digits
+ *
+ * - if nd > 9, z contains the value represented by significant digits
+ * with indices in [9, min(16, nd)). So y * 10**(min(16, nd) - 9) + z
+ * gives the value represented by the first min(16, nd) sig. digits.
+ */
+
+ bc.e0 = e1 = e;
+ y = z = 0;
+ for (i = 0; i < nd; i++) {
+ if (i < 9)
+ y = 10*y + s0[i < nd0 ? i : i+1] - '0';
+ else if (i < DBL_DIG+1)
+ z = 10*z + s0[i < nd0 ? i : i+1] - '0';
+ else
+ break;
+ }
+
+ k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
+ dval(&rv) = y;
+ if (k > 9) {
+ dval(&rv) = tens[k - 9] * dval(&rv) + z;
+ }
+ if (nd <= DBL_DIG
+ && Flt_Rounds == 1
+ ) {
+ if (!e)
+ goto ret;
+ if (e > 0) {
+ if (e <= Ten_pmax) {
+ dval(&rv) *= tens[e];
+ goto ret;
+ }
+ i = DBL_DIG - nd;
+ if (e <= Ten_pmax + i) {
+ /* A fancier test would sometimes let us do
+ * this for larger i values.
+ */
+ e -= i;
+ dval(&rv) *= tens[i];
+ dval(&rv) *= tens[e];
+ goto ret;
+ }
+ }
+ else if (e >= -Ten_pmax) {
+ dval(&rv) /= tens[-e];
+ goto ret;
+ }
+ }
+ e1 += nd - k;
+
+ bc.scale = 0;
+
+ /* Get starting approximation = rv * 10**e1 */
+
+ if (e1 > 0) {
+ if ((i = e1 & 15))
+ dval(&rv) *= tens[i];
+ if (e1 &= ~15) {
+ if (e1 > DBL_MAX_10_EXP)
+ goto ovfl;
+ e1 >>= 4;
+ for(j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ dval(&rv) *= bigtens[j];
+ /* The last multiplication could overflow. */
+ word0(&rv) -= P*Exp_msk1;
+ dval(&rv) *= bigtens[j];
+ if ((z = word0(&rv) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-P))
+ goto ovfl;
+ if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
+ /* set to largest number */
+ /* (Can't trust DBL_MAX) */
+ word0(&rv) = Big0;
+ word1(&rv) = Big1;
+ }
+ else
+ word0(&rv) += P*Exp_msk1;
+ }
+ }
+ else if (e1 < 0) {
+ /* The input decimal value lies in [10**e1, 10**(e1+16)).
+
+ If e1 <= -512, underflow immediately.
+ If e1 <= -256, set bc.scale to 2*P.
+
+ So for input value < 1e-256, bc.scale is always set;
+ for input value >= 1e-240, bc.scale is never set.
+ For input values in [1e-256, 1e-240), bc.scale may or may
+ not be set. */
+
+ e1 = -e1;
+ if ((i = e1 & 15))
+ dval(&rv) /= tens[i];
+ if (e1 >>= 4) {
+ if (e1 >= 1 << n_bigtens)
+ goto undfl;
+ if (e1 & Scale_Bit)
+ bc.scale = 2*P;
+ for(j = 0; e1 > 0; j++, e1 >>= 1)
+ if (e1 & 1)
+ dval(&rv) *= tinytens[j];
+ if (bc.scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask)
+ >> Exp_shift)) > 0) {
+ /* scaled rv is denormal; clear j low bits */
+ if (j >= 32) {
+ word1(&rv) = 0;
+ if (j >= 53)
+ word0(&rv) = (P+2)*Exp_msk1;
+ else
+ word0(&rv) &= 0xffffffff << (j-32);
+ }
+ else
+ word1(&rv) &= 0xffffffff << j;
+ }
+ if (!dval(&rv))
+ goto undfl;
+ }
+ }
+
+ /* Now the hard part -- adjusting rv to the correct value.*/
+
+ /* Put digits into bd: true value = bd * 10^e */
+
+ bc.nd = nd;
+ bc.nd0 = nd0; /* Only needed if nd > STRTOD_DIGLIM, but done here */
+ /* to silence an erroneous warning about bc.nd0 */
+ /* possibly not being initialized. */
+ if (nd > STRTOD_DIGLIM) {
+ /* ASSERT(STRTOD_DIGLIM >= 18); 18 == one more than the */
+ /* minimum number of decimal digits to distinguish double values */
+ /* in IEEE arithmetic. */
+
+ /* Truncate input to 18 significant digits, then discard any trailing
+ zeros on the result by updating nd, nd0, e and y suitably. (There's
+ no need to update z; it's not reused beyond this point.) */
+ for (i = 18; i > 0; ) {
+ /* scan back until we hit a nonzero digit. significant digit 'i'
+ is s0[i] if i < nd0, s0[i+1] if i >= nd0. */
+ --i;
+ if (s0[i < nd0 ? i : i+1] != '0') {
+ ++i;
+ break;
+ }
+ }
+ e += nd - i;
+ nd = i;
+ if (nd0 > nd)
+ nd0 = nd;
+ if (nd < 9) { /* must recompute y */
+ y = 0;
+ for(i = 0; i < nd0; ++i)
+ y = 10*y + s0[i] - '0';
+ for(; i < nd; ++i)
+ y = 10*y + s0[i+1] - '0';
+ }
+ }
+ bd0 = s2b(s0, nd0, nd, y);
+ if (bd0 == NULL)
+ goto failed_malloc;
+
+ /* Notation for the comments below. Write:
+
+ - dv for the absolute value of the number represented by the original
+ decimal input string.
+
+ - if we've truncated dv, write tdv for the truncated value.
+ Otherwise, set tdv == dv.
+
+ - srv for the quantity rv/2^bc.scale; so srv is the current binary
+ approximation to tdv (and dv). It should be exactly representable
+ in an IEEE 754 double.
+ */
+
+ for(;;) {
+
+ /* This is the main correction loop for _Py_dg_strtod.
+
+ We've got a decimal value tdv, and a floating-point approximation
+ srv=rv/2^bc.scale to tdv. The aim is to determine whether srv is
+ close enough (i.e., within 0.5 ulps) to tdv, and to compute a new
+ approximation if not.
+
+ To determine whether srv is close enough to tdv, compute integers
+ bd, bb and bs proportional to tdv, srv and 0.5 ulp(srv)
+ respectively, and then use integer arithmetic to determine whether
+ |tdv - srv| is less than, equal to, or greater than 0.5 ulp(srv).
+ */
+
+ bd = Balloc(bd0->k);
+ if (bd == NULL) {
+ goto failed_malloc;
+ }
+ Bcopy(bd, bd0);
+ bb = sd2b(&rv, bc.scale, &bbe); /* srv = bb * 2^bbe */
+ if (bb == NULL) {
+ goto failed_malloc;
+ }
+ /* Record whether lsb of bb is odd, in case we need this
+ for the round-to-even step later. */
+ odd = bb->x[0] & 1;
+
+ /* tdv = bd * 10**e; srv = bb * 2**bbe */
+ bs = i2b(1);
+ if (bs == NULL) {
+ goto failed_malloc;
+ }
+
+ if (e >= 0) {
+ bb2 = bb5 = 0;
+ bd2 = bd5 = e;
+ }
+ else {
+ bb2 = bb5 = -e;
+ bd2 = bd5 = 0;
+ }
+ if (bbe >= 0)
+ bb2 += bbe;
+ else
+ bd2 -= bbe;
+ bs2 = bb2;
+ bb2++;
+ bd2++;
+
+ /* At this stage bd5 - bb5 == e == bd2 - bb2 + bbe, bb2 - bs2 == 1,
+ and bs == 1, so:
+
+ tdv == bd * 10**e = bd * 2**(bbe - bb2 + bd2) * 5**(bd5 - bb5)
+ srv == bb * 2**bbe = bb * 2**(bbe - bb2 + bb2)
+ 0.5 ulp(srv) == 2**(bbe-1) = bs * 2**(bbe - bb2 + bs2)
+
+ It follows that:
+
+ M * tdv = bd * 2**bd2 * 5**bd5
+ M * srv = bb * 2**bb2 * 5**bb5
+ M * 0.5 ulp(srv) = bs * 2**bs2 * 5**bb5
+
+ for some constant M. (Actually, M == 2**(bb2 - bbe) * 5**bb5, but
+ this fact is not needed below.)
+ */
+
+ /* Remove factor of 2**i, where i = min(bb2, bd2, bs2). */
+ i = bb2 < bd2 ? bb2 : bd2;
+ if (i > bs2)
+ i = bs2;
+ if (i > 0) {
+ bb2 -= i;
+ bd2 -= i;
+ bs2 -= i;
+ }
+
+ /* Scale bb, bd, bs by the appropriate powers of 2 and 5. */
+ if (bb5 > 0) {
+ bs = pow5mult(bs, bb5);
+ if (bs == NULL) {
+ goto failed_malloc;
+ }
+ Bigint *bb1 = mult(bs, bb);
+ Bfree(bb);
+ bb = bb1;
+ if (bb == NULL) {
+ goto failed_malloc;
+ }
+ }
+ if (bb2 > 0) {
+ bb = lshift(bb, bb2);
+ if (bb == NULL) {
+ goto failed_malloc;
+ }
+ }
+ if (bd5 > 0) {
+ bd = pow5mult(bd, bd5);
+ if (bd == NULL) {
+ goto failed_malloc;
+ }
+ }
+ if (bd2 > 0) {
+ bd = lshift(bd, bd2);
+ if (bd == NULL) {
+ goto failed_malloc;
+ }
+ }
+ if (bs2 > 0) {
+ bs = lshift(bs, bs2);
+ if (bs == NULL) {
+ goto failed_malloc;
+ }
+ }
+
+ /* Now bd, bb and bs are scaled versions of tdv, srv and 0.5 ulp(srv),
+ respectively. Compute the difference |tdv - srv|, and compare
+ with 0.5 ulp(srv). */
+
+ delta = diff(bb, bd);
+ if (delta == NULL) {
+ goto failed_malloc;
+ }
+ dsign = delta->sign;
+ delta->sign = 0;
+ i = cmp(delta, bs);
+ if (bc.nd > nd && i <= 0) {
+ if (dsign)
+ break; /* Must use bigcomp(). */
+
+ /* Here rv overestimates the truncated decimal value by at most
+ 0.5 ulp(rv). Hence rv either overestimates the true decimal
+ value by <= 0.5 ulp(rv), or underestimates it by some small
+ amount (< 0.1 ulp(rv)); either way, rv is within 0.5 ulps of
+ the true decimal value, so it's possible to exit.
+
+ Exception: if scaled rv is a normal exact power of 2, but not
+ DBL_MIN, then rv - 0.5 ulp(rv) takes us all the way down to the
+ next double, so the correctly rounded result is either rv - 0.5
+ ulp(rv) or rv; in this case, use bigcomp to distinguish. */
+
+ if (!word1(&rv) && !(word0(&rv) & Bndry_mask)) {
+ /* rv can't be 0, since it's an overestimate for some
+ nonzero value. So rv is a normal power of 2. */
+ j = (int)(word0(&rv) & Exp_mask) >> Exp_shift;
+ /* rv / 2^bc.scale = 2^(j - 1023 - bc.scale); use bigcomp if
+ rv / 2^bc.scale >= 2^-1021. */
+ if (j - bc.scale >= 2) {
+ dval(&rv) -= 0.5 * sulp(&rv, &bc);
+ break; /* Use bigcomp. */
+ }
+ }
+
+ {
+ bc.nd = nd;
+ i = -1; /* Discarded digits make delta smaller. */
+ }
+ }
+
+ if (i < 0) {
+ /* Error is less than half an ulp -- check for
+ * special case of mantissa a power of two.
+ */
+ if (dsign || word1(&rv) || word0(&rv) & Bndry_mask
+ || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1
+ ) {
+ break;
+ }
+ if (!delta->x[0] && delta->wds <= 1) {
+ /* exact result */
+ break;
+ }
+ delta = lshift(delta,Log2P);
+ if (delta == NULL) {
+ goto failed_malloc;
+ }
+ if (cmp(delta, bs) > 0)
+ goto drop_down;
+ break;
+ }
+ if (i == 0) {
+ /* exactly half-way between */
+ if (dsign) {
+ if ((word0(&rv) & Bndry_mask1) == Bndry_mask1
+ && word1(&rv) == (
+ (bc.scale &&
+ (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) ?
+ (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :
+ 0xffffffff)) {
+ /*boundary case -- increment exponent*/
+ word0(&rv) = (word0(&rv) & Exp_mask)
+ + Exp_msk1
+ ;
+ word1(&rv) = 0;
+ /* dsign = 0; */
+ break;
+ }
+ }
+ else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) {
+ drop_down:
+ /* boundary case -- decrement exponent */
+ if (bc.scale) {
+ L = word0(&rv) & Exp_mask;
+ if (L <= (2*P+1)*Exp_msk1) {
+ if (L > (P+2)*Exp_msk1)
+ /* round even ==> */
+ /* accept rv */
+ break;
+ /* rv = smallest denormal */
+ if (bc.nd > nd)
+ break;
+ goto undfl;
+ }
+ }
+ L = (word0(&rv) & Exp_mask) - Exp_msk1;
+ word0(&rv) = L | Bndry_mask1;
+ word1(&rv) = 0xffffffff;
+ break;
+ }
+ if (!odd)
+ break;
+ if (dsign)
+ dval(&rv) += sulp(&rv, &bc);
+ else {
+ dval(&rv) -= sulp(&rv, &bc);
+ if (!dval(&rv)) {
+ if (bc.nd >nd)
+ break;
+ goto undfl;
+ }
+ }
+ /* dsign = 1 - dsign; */
+ break;
+ }
+ if ((aadj = ratio(delta, bs)) <= 2.) {
+ if (dsign)
+ aadj = aadj1 = 1.;
+ else if (word1(&rv) || word0(&rv) & Bndry_mask) {
+ if (word1(&rv) == Tiny1 && !word0(&rv)) {
+ if (bc.nd >nd)
+ break;
+ goto undfl;
+ }
+ aadj = 1.;
+ aadj1 = -1.;
+ }
+ else {
+ /* special case -- power of FLT_RADIX to be */
+ /* rounded down... */
+
+ if (aadj < 2./FLT_RADIX)
+ aadj = 1./FLT_RADIX;
+ else
+ aadj *= 0.5;
+ aadj1 = -aadj;
+ }
+ }
+ else {
+ aadj *= 0.5;
+ aadj1 = dsign ? aadj : -aadj;
+ if (Flt_Rounds == 0)
+ aadj1 += 0.5;
+ }
+ y = word0(&rv) & Exp_mask;
+
+ /* Check for overflow */
+
+ if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
+ dval(&rv0) = dval(&rv);
+ word0(&rv) -= P*Exp_msk1;
+ adj.d = aadj1 * ulp(&rv);
+ dval(&rv) += adj.d;
+ if ((word0(&rv) & Exp_mask) >=
+ Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
+ if (word0(&rv0) == Big0 && word1(&rv0) == Big1) {
+ goto ovfl;
+ }
+ word0(&rv) = Big0;
+ word1(&rv) = Big1;
+ goto cont;
+ }
+ else
+ word0(&rv) += P*Exp_msk1;
+ }
+ else {
+ if (bc.scale && y <= 2*P*Exp_msk1) {
+ if (aadj <= 0x7fffffff) {
+ if ((z = (ULong)aadj) <= 0)
+ z = 1;
+ aadj = z;
+ aadj1 = dsign ? aadj : -aadj;
+ }
+ dval(&aadj2) = aadj1;
+ word0(&aadj2) += (2*P+1)*Exp_msk1 - y;
+ aadj1 = dval(&aadj2);
+ }
+ adj.d = aadj1 * ulp(&rv);
+ dval(&rv) += adj.d;
+ }
+ z = word0(&rv) & Exp_mask;
+ if (bc.nd == nd) {
+ if (!bc.scale)
+ if (y == z) {
+ /* Can we stop now? */
+ L = (Long)aadj;
+ aadj -= L;
+ /* The tolerances below are conservative. */
+ if (dsign || word1(&rv) || word0(&rv) & Bndry_mask) {
+ if (aadj < .4999999 || aadj > .5000001)
+ break;
+ }
+ else if (aadj < .4999999/FLT_RADIX)
+ break;
+ }
+ }
+ cont:
+ Bfree(bb); bb = NULL;
+ Bfree(bd); bd = NULL;
+ Bfree(bs); bs = NULL;
+ Bfree(delta); delta = NULL;
+ }
+ if (bc.nd > nd) {
+ error = bigcomp(&rv, s0, &bc);
+ if (error)
+ goto failed_malloc;
+ }
+
+ if (bc.scale) {
+ word0(&rv0) = Exp_1 - 2*P*Exp_msk1;
+ word1(&rv0) = 0;
+ dval(&rv) *= dval(&rv0);
+ }
+
+ ret:
+ result = sign ? -dval(&rv) : dval(&rv);
+ goto done;
+
+ parse_error:
+ result = 0.0;
+ goto done;
+
+ failed_malloc:
+ errno = ENOMEM;
+ result = -1.0;
+ goto done;
+
+ undfl:
+ result = sign ? -0.0 : 0.0;
+ goto done;
+
+ ovfl:
+ errno = ERANGE;
+ /* Can't trust HUGE_VAL */
+ word0(&rv) = Exp_mask;
+ word1(&rv) = 0;
+ result = sign ? -dval(&rv) : dval(&rv);
+ goto done;
+
+ done:
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(bd0);
+ Bfree(delta);
+ return result;
+
+}
+
+static char *
+rv_alloc(int i)
+{
+ int j, k, *r;
+
+ j = sizeof(ULong);
+ for(k = 0;
+ sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= (unsigned)i;
+ j <<= 1)
+ k++;
+ r = (int*)Balloc(k);
+ if (r == NULL)
+ return NULL;
+ *r = k;
+ return (char *)(r+1);
+}
+
+static char *
+nrv_alloc(const char *s, char **rve, int n)
+{
+ char *rv, *t;
+
+ rv = rv_alloc(n);
+ if (rv == NULL)
+ return NULL;
+ t = rv;
+ while((*t = *s++)) t++;
+ if (rve)
+ *rve = t;
+ return rv;
+}
+
+/* freedtoa(s) must be used to free values s returned by dtoa
+ * when MULTIPLE_THREADS is #defined. It should be used in all cases,
+ * but for consistency with earlier versions of dtoa, it is optional
+ * when MULTIPLE_THREADS is not defined.
+ */
+
+void
+_Py_dg_freedtoa(char *s)
+{
+ Bigint *b = (Bigint *)((int *)s - 1);
+ b->maxwds = 1 << (b->k = *(int*)b);
+ Bfree(b);
+}
+
+/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
+ *
+ * Inspired by "How to Print Floating-Point Numbers Accurately" by
+ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].
+ *
+ * Modifications:
+ * 1. Rather than iterating, we use a simple numeric overestimate
+ * to determine k = floor(log10(d)). We scale relevant
+ * quantities using O(log2(k)) rather than O(k) multiplications.
+ * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
+ * try to generate digits strictly left to right. Instead, we
+ * compute with fewer bits and propagate the carry if necessary
+ * when rounding the final digit up. This is often faster.
+ * 3. Under the assumption that input will be rounded nearest,
+ * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
+ * That is, we allow equality in stopping tests when the
+ * round-nearest rule will give the same floating-point value
+ * as would satisfaction of the stopping test with strict
+ * inequality.
+ * 4. We remove common factors of powers of 2 from relevant
+ * quantities.
+ * 5. When converting floating-point integers less than 1e16,
+ * we use floating-point arithmetic rather than resorting
+ * to multiple-precision integers.
+ * 6. When asked to produce fewer than 15 digits, we first try
+ * to get by with floating-point arithmetic; we resort to
+ * multiple-precision integer arithmetic only if we cannot
+ * guarantee that the floating-point calculation has given
+ * the correctly rounded result. For k requested digits and
+ * "uniformly" distributed input, the probability is
+ * something like 10^(k-15) that we must resort to the Long
+ * calculation.
+ */
+
+/* Additional notes (METD): (1) returns NULL on failure. (2) to avoid memory
+ leakage, a successful call to _Py_dg_dtoa should always be matched by a
+ call to _Py_dg_freedtoa. */
+
+char *
+_Py_dg_dtoa(double dd, int mode, int ndigits,
+ int *decpt, int *sign, char **rve)
+{
+ /* Arguments ndigits, decpt, sign are similar to those
+ of ecvt and fcvt; trailing zeros are suppressed from
+ the returned string. If not null, *rve is set to point
+ to the end of the return value. If d is +-Infinity or NaN,
+ then *decpt is set to 9999.
+
+ mode:
+ 0 ==> shortest string that yields d when read in
+ and rounded to nearest.
+ 1 ==> like 0, but with Steele & White stopping rule;
+ e.g. with IEEE P754 arithmetic , mode 0 gives
+ 1e23 whereas mode 1 gives 9.999999999999999e22.
+ 2 ==> max(1,ndigits) significant digits. This gives a
+ return value similar to that of ecvt, except
+ that trailing zeros are suppressed.
+ 3 ==> through ndigits past the decimal point. This
+ gives a return value similar to that from fcvt,
+ except that trailing zeros are suppressed, and
+ ndigits can be negative.
+ 4,5 ==> similar to 2 and 3, respectively, but (in
+ round-nearest mode) with the tests of mode 0 to
+ possibly return a shorter string that rounds to d.
+ With IEEE arithmetic and compilation with
+ -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same
+ as modes 2 and 3 when FLT_ROUNDS != 1.
+ 6-9 ==> Debugging modes similar to mode - 4: don't try
+ fast floating-point estimate (if applicable).
+
+ Values of mode other than 0-9 are treated as mode 0.
+
+ Sufficient space is allocated to the return value
+ to hold the suppressed trailing zeros.
+ */
+
+ int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
+ j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
+ spec_case, try_quick;
+ Long L;
+ int denorm;
+ ULong x;
+ Bigint *b, *b1, *delta, *mlo, *mhi, *S;
+ U d2, eps, u;
+ double ds;
+ char *s, *s0;
+
+ /* set pointers to NULL, to silence gcc compiler warnings and make
+ cleanup easier on error */
+ mlo = mhi = S = 0;
+ s0 = 0;
+
+ u.d = dd;
+ if (word0(&u) & Sign_bit) {
+ /* set sign for everything, including 0's and NaNs */
+ *sign = 1;
+ word0(&u) &= ~Sign_bit; /* clear sign bit */
+ }
+ else
+ *sign = 0;
+
+ /* quick return for Infinities, NaNs and zeros */
+ if ((word0(&u) & Exp_mask) == Exp_mask)
+ {
+ /* Infinity or NaN */
+ *decpt = 9999;
+ if (!word1(&u) && !(word0(&u) & 0xfffff))
+ return nrv_alloc("Infinity", rve, 8);
+ return nrv_alloc("NaN", rve, 3);
+ }
+ if (!dval(&u)) {
+ *decpt = 1;
+ return nrv_alloc("0", rve, 1);
+ }
+
+ /* compute k = floor(log10(d)). The computation may leave k
+ one too large, but should never leave k too small. */
+ b = d2b(&u, &be, &bbits);
+ if (b == NULL)
+ goto failed_malloc;
+ if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) {
+ dval(&d2) = dval(&u);
+ word0(&d2) &= Frac_mask1;
+ word0(&d2) |= Exp_11;
+
+ /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
+ * log10(x) = log(x) / log(10)
+ * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
+ * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
+ *
+ * This suggests computing an approximation k to log10(d) by
+ *
+ * k = (i - Bias)*0.301029995663981
+ * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
+ *
+ * We want k to be too large rather than too small.
+ * The error in the first-order Taylor series approximation
+ * is in our favor, so we just round up the constant enough
+ * to compensate for any error in the multiplication of
+ * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
+ * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
+ * adding 1e-13 to the constant term more than suffices.
+ * Hence we adjust the constant term to 0.1760912590558.
+ * (We could get a more accurate k by invoking log10,
+ * but this is probably not worthwhile.)
+ */
+
+ i -= Bias;
+ denorm = 0;
+ }
+ else {
+ /* d is denormalized */
+
+ i = bbits + be + (Bias + (P-1) - 1);
+ x = i > 32 ? word0(&u) << (64 - i) | word1(&u) >> (i - 32)
+ : word1(&u) << (32 - i);
+ dval(&d2) = x;
+ word0(&d2) -= 31*Exp_msk1; /* adjust exponent */
+ i -= (Bias + (P-1) - 1) + 1;
+ denorm = 1;
+ }
+ ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 +
+ i*0.301029995663981;
+ k = (int)ds;
+ if (ds < 0. && ds != k)
+ k--; /* want k = floor(ds) */
+ k_check = 1;
+ if (k >= 0 && k <= Ten_pmax) {
+ if (dval(&u) < tens[k])
+ k--;
+ k_check = 0;
+ }
+ j = bbits - i - 1;
+ if (j >= 0) {
+ b2 = 0;
+ s2 = j;
+ }
+ else {
+ b2 = -j;
+ s2 = 0;
+ }
+ if (k >= 0) {
+ b5 = 0;
+ s5 = k;
+ s2 += k;
+ }
+ else {
+ b2 -= k;
+ b5 = -k;
+ s5 = 0;
+ }
+ if (mode < 0 || mode > 9)
+ mode = 0;
+
+ try_quick = 1;
+
+ if (mode > 5) {
+ mode -= 4;
+ try_quick = 0;
+ }
+ leftright = 1;
+ ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */
+ /* silence erroneous "gcc -Wall" warning. */
+ switch(mode) {
+ case 0:
+ case 1:
+ i = 18;
+ ndigits = 0;
+ break;
+ case 2:
+ leftright = 0;
+ /* fall through */
+ case 4:
+ if (ndigits <= 0)
+ ndigits = 1;
+ ilim = ilim1 = i = ndigits;
+ break;
+ case 3:
+ leftright = 0;
+ /* fall through */
+ case 5:
+ i = ndigits + k + 1;
+ ilim = i;
+ ilim1 = i - 1;
+ if (i <= 0)
+ i = 1;
+ }
+ s0 = rv_alloc(i);
+ if (s0 == NULL)
+ goto failed_malloc;
+ s = s0;
+
+
+ if (ilim >= 0 && ilim <= Quick_max && try_quick) {
+
+ /* Try to get by with floating-point arithmetic. */
+
+ i = 0;
+ dval(&d2) = dval(&u);
+ k0 = k;
+ ilim0 = ilim;
+ ieps = 2; /* conservative */
+ if (k > 0) {
+ ds = tens[k&0xf];
+ j = k >> 4;
+ if (j & Bletch) {
+ /* prevent overflows */
+ j &= Bletch - 1;
+ dval(&u) /= bigtens[n_bigtens-1];
+ ieps++;
+ }
+ for(; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ ds *= bigtens[i];
+ }
+ dval(&u) /= ds;
+ }
+ else if ((j1 = -k)) {
+ dval(&u) *= tens[j1 & 0xf];
+ for(j = j1 >> 4; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ dval(&u) *= bigtens[i];
+ }
+ }
+ if (k_check && dval(&u) < 1. && ilim > 0) {
+ if (ilim1 <= 0)
+ goto fast_failed;
+ ilim = ilim1;
+ k--;
+ dval(&u) *= 10.;
+ ieps++;
+ }
+ dval(&eps) = ieps*dval(&u) + 7.;
+ word0(&eps) -= (P-1)*Exp_msk1;
+ if (ilim == 0) {
+ S = mhi = 0;
+ dval(&u) -= 5.;
+ if (dval(&u) > dval(&eps))
+ goto one_digit;
+ if (dval(&u) < -dval(&eps))
+ goto no_digits;
+ goto fast_failed;
+ }
+ if (leftright) {
+ /* Use Steele & White method of only
+ * generating digits needed.
+ */
+ dval(&eps) = 0.5/tens[ilim-1] - dval(&eps);
+ for(i = 0;;) {
+ L = (Long)dval(&u);
+ dval(&u) -= L;
+ *s++ = '0' + (int)L;
+ if (dval(&u) < dval(&eps))
+ goto ret1;
+ if (1. - dval(&u) < dval(&eps))
+ goto bump_up;
+ if (++i >= ilim)
+ break;
+ dval(&eps) *= 10.;
+ dval(&u) *= 10.;
+ }
+ }
+ else {
+ /* Generate ilim digits, then fix them up. */
+ dval(&eps) *= tens[ilim-1];
+ for(i = 1;; i++, dval(&u) *= 10.) {
+ L = (Long)(dval(&u));
+ if (!(dval(&u) -= L))
+ ilim = i;
+ *s++ = '0' + (int)L;
+ if (i == ilim) {
+ if (dval(&u) > 0.5 + dval(&eps))
+ goto bump_up;
+ else if (dval(&u) < 0.5 - dval(&eps)) {
+ while(*--s == '0');
+ s++;
+ goto ret1;
+ }
+ break;
+ }
+ }
+ }
+ fast_failed:
+ s = s0;
+ dval(&u) = dval(&d2);
+ k = k0;
+ ilim = ilim0;
+ }
+
+ /* Do we have a "small" integer? */
+
+ if (be >= 0 && k <= Int_max) {
+ /* Yes. */
+ ds = tens[k];
+ if (ndigits < 0 && ilim <= 0) {
+ S = mhi = 0;
+ if (ilim < 0 || dval(&u) <= 5*ds)
+ goto no_digits;
+ goto one_digit;
+ }
+ for(i = 1;; i++, dval(&u) *= 10.) {
+ L = (Long)(dval(&u) / ds);
+ dval(&u) -= L*ds;
+ *s++ = '0' + (int)L;
+ if (!dval(&u)) {
+ break;
+ }
+ if (i == ilim) {
+ dval(&u) += dval(&u);
+ if (dval(&u) > ds || (dval(&u) == ds && L & 1)) {
+ bump_up:
+ while(*--s == '9')
+ if (s == s0) {
+ k++;
+ *s = '0';
+ break;
+ }
+ ++*s++;
+ }
+ else {
+ /* Strip trailing zeros. This branch was missing from the
+ original dtoa.c, leading to surplus trailing zeros in
+ some cases. See bugs.python.org/issue40780. */
+ while (s > s0 && s[-1] == '0') {
+ --s;
+ }
+ }
+ break;
+ }
+ }
+ goto ret1;
+ }
+
+ m2 = b2;
+ m5 = b5;
+ if (leftright) {
+ i =
+ denorm ? be + (Bias + (P-1) - 1 + 1) :
+ 1 + P - bbits;
+ b2 += i;
+ s2 += i;
+ mhi = i2b(1);
+ if (mhi == NULL)
+ goto failed_malloc;
+ }
+ if (m2 > 0 && s2 > 0) {
+ i = m2 < s2 ? m2 : s2;
+ b2 -= i;
+ m2 -= i;
+ s2 -= i;
+ }
+ if (b5 > 0) {
+ if (leftright) {
+ if (m5 > 0) {
+ mhi = pow5mult(mhi, m5);
+ if (mhi == NULL)
+ goto failed_malloc;
+ b1 = mult(mhi, b);
+ Bfree(b);
+ b = b1;
+ if (b == NULL)
+ goto failed_malloc;
+ }
+ if ((j = b5 - m5)) {
+ b = pow5mult(b, j);
+ if (b == NULL)
+ goto failed_malloc;
+ }
+ }
+ else {
+ b = pow5mult(b, b5);
+ if (b == NULL)
+ goto failed_malloc;
+ }
+ }
+ S = i2b(1);
+ if (S == NULL)
+ goto failed_malloc;
+ if (s5 > 0) {
+ S = pow5mult(S, s5);
+ if (S == NULL)
+ goto failed_malloc;
+ }
+
+ /* Check for special case that d is a normalized power of 2. */
+
+ spec_case = 0;
+ if ((mode < 2 || leftright)
+ ) {
+ if (!word1(&u) && !(word0(&u) & Bndry_mask)
+ && word0(&u) & (Exp_mask & ~Exp_msk1)
+ ) {
+ /* The special case */
+ b2 += Log2P;
+ s2 += Log2P;
+ spec_case = 1;
+ }
+ }
+
+ /* Arrange for convenient computation of quotients:
+ * shift left if necessary so divisor has 4 leading 0 bits.
+ *
+ * Perhaps we should just compute leading 28 bits of S once
+ * and for all and pass them and a shift to quorem, so it
+ * can do shifts and ors to compute the numerator for q.
+ */
+#define iInc 28
+ i = dshift(S, s2);
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ if (b2 > 0) {
+ b = lshift(b, b2);
+ if (b == NULL)
+ goto failed_malloc;
+ }
+ if (s2 > 0) {
+ S = lshift(S, s2);
+ if (S == NULL)
+ goto failed_malloc;
+ }
+ if (k_check) {
+ if (cmp(b,S) < 0) {
+ k--;
+ b = multadd(b, 10, 0); /* we botched the k estimate */
+ if (b == NULL)
+ goto failed_malloc;
+ if (leftright) {
+ mhi = multadd(mhi, 10, 0);
+ if (mhi == NULL)
+ goto failed_malloc;
+ }
+ ilim = ilim1;
+ }
+ }
+ if (ilim <= 0 && (mode == 3 || mode == 5)) {
+ if (ilim < 0) {
+ /* no digits, fcvt style */
+ no_digits:
+ k = -1 - ndigits;
+ goto ret;
+ }
+ else {
+ S = multadd(S, 5, 0);
+ if (S == NULL)
+ goto failed_malloc;
+ if (cmp(b, S) <= 0)
+ goto no_digits;
+ }
+ one_digit:
+ *s++ = '1';
+ k++;
+ goto ret;
+ }
+ if (leftright) {
+ if (m2 > 0) {
+ mhi = lshift(mhi, m2);
+ if (mhi == NULL)
+ goto failed_malloc;
+ }
+
+ /* Compute mlo -- check for special case
+ * that d is a normalized power of 2.
+ */
+
+ mlo = mhi;
+ if (spec_case) {
+ mhi = Balloc(mhi->k);
+ if (mhi == NULL)
+ goto failed_malloc;
+ Bcopy(mhi, mlo);
+ mhi = lshift(mhi, Log2P);
+ if (mhi == NULL)
+ goto failed_malloc;
+ }
+
+ for(i = 1;;i++) {
+ dig = quorem(b,S) + '0';
+ /* Do we yet have the shortest decimal string
+ * that will round to d?
+ */
+ j = cmp(b, mlo);
+ delta = diff(S, mhi);
+ if (delta == NULL)
+ goto failed_malloc;
+ j1 = delta->sign ? 1 : cmp(b, delta);
+ Bfree(delta);
+ if (j1 == 0 && mode != 1 && !(word1(&u) & 1)
+ ) {
+ if (dig == '9')
+ goto round_9_up;
+ if (j > 0)
+ dig++;
+ *s++ = dig;
+ goto ret;
+ }
+ if (j < 0 || (j == 0 && mode != 1
+ && !(word1(&u) & 1)
+ )) {
+ if (!b->x[0] && b->wds <= 1) {
+ goto accept_dig;
+ }
+ if (j1 > 0) {
+ b = lshift(b, 1);
+ if (b == NULL)
+ goto failed_malloc;
+ j1 = cmp(b, S);
+ if ((j1 > 0 || (j1 == 0 && dig & 1))
+ && dig++ == '9')
+ goto round_9_up;
+ }
+ accept_dig:
+ *s++ = dig;
+ goto ret;
+ }
+ if (j1 > 0) {
+ if (dig == '9') { /* possible if i == 1 */
+ round_9_up:
+ *s++ = '9';
+ goto roundoff;
+ }
+ *s++ = dig + 1;
+ goto ret;
+ }
+ *s++ = dig;
+ if (i == ilim)
+ break;
+ b = multadd(b, 10, 0);
+ if (b == NULL)
+ goto failed_malloc;
+ if (mlo == mhi) {
+ mlo = mhi = multadd(mhi, 10, 0);
+ if (mlo == NULL)
+ goto failed_malloc;
+ }
+ else {
+ mlo = multadd(mlo, 10, 0);
+ if (mlo == NULL)
+ goto failed_malloc;
+ mhi = multadd(mhi, 10, 0);
+ if (mhi == NULL)
+ goto failed_malloc;
+ }
+ }
+ }
+ else
+ for(i = 1;; i++) {
+ *s++ = dig = quorem(b,S) + '0';
+ if (!b->x[0] && b->wds <= 1) {
+ goto ret;
+ }
+ if (i >= ilim)
+ break;
+ b = multadd(b, 10, 0);
+ if (b == NULL)
+ goto failed_malloc;
+ }
+
+ /* Round off last digit */
+
+ b = lshift(b, 1);
+ if (b == NULL)
+ goto failed_malloc;
+ j = cmp(b, S);
+ if (j > 0 || (j == 0 && dig & 1)) {
+ roundoff:
+ while(*--s == '9')
+ if (s == s0) {
+ k++;
+ *s++ = '1';
+ goto ret;
+ }
+ ++*s++;
+ }
+ else {
+ while(*--s == '0');
+ s++;
+ }
+ ret:
+ Bfree(S);
+ if (mhi) {
+ if (mlo && mlo != mhi)
+ Bfree(mlo);
+ Bfree(mhi);
+ }
+ ret1:
+ Bfree(b);
+ *s = 0;
+ *decpt = k + 1;
+ if (rve)
+ *rve = s;
+ return s0;
+ failed_malloc:
+ if (S)
+ Bfree(S);
+ if (mlo && mlo != mhi)
+ Bfree(mlo);
+ if (mhi)
+ Bfree(mhi);
+ if (b)
+ Bfree(b);
+ if (s0)
+ _Py_dg_freedtoa(s0);
+ return NULL;
+}
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PY_NO_SHORT_FLOAT_REPR */
diff --git a/contrib/tools/python3/src/Python/dynamic_annotations.c b/contrib/tools/python3/src/Python/dynamic_annotations.c
new file mode 100644
index 00000000000..7febaa09df1
--- /dev/null
+++ b/contrib/tools/python3/src/Python/dynamic_annotations.c
@@ -0,0 +1,154 @@
+/* Copyright (c) 2008-2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Kostya Serebryany
+ */
+
+#ifdef _MSC_VER
+# include <windows.h>
+#endif
+
+#ifdef __cplusplus
+# error "This file should be built as pure C to avoid name mangling"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "dynamic_annotations.h"
+
+/* Each function is empty and called (via a macro) only in debug mode.
+ The arguments are captured by dynamic tools at runtime. */
+
+#if DYNAMIC_ANNOTATIONS_ENABLED == 1
+
+void AnnotateRWLockCreate(const char *file, int line,
+ const volatile void *lock){}
+void AnnotateRWLockDestroy(const char *file, int line,
+ const volatile void *lock){}
+void AnnotateRWLockAcquired(const char *file, int line,
+ const volatile void *lock, long is_w){}
+void AnnotateRWLockReleased(const char *file, int line,
+ const volatile void *lock, long is_w){}
+void AnnotateBarrierInit(const char *file, int line,
+ const volatile void *barrier, long count,
+ long reinitialization_allowed) {}
+void AnnotateBarrierWaitBefore(const char *file, int line,
+ const volatile void *barrier) {}
+void AnnotateBarrierWaitAfter(const char *file, int line,
+ const volatile void *barrier) {}
+void AnnotateBarrierDestroy(const char *file, int line,
+ const volatile void *barrier) {}
+
+void AnnotateCondVarWait(const char *file, int line,
+ const volatile void *cv,
+ const volatile void *lock){}
+void AnnotateCondVarSignal(const char *file, int line,
+ const volatile void *cv){}
+void AnnotateCondVarSignalAll(const char *file, int line,
+ const volatile void *cv){}
+void AnnotatePublishMemoryRange(const char *file, int line,
+ const volatile void *address,
+ long size){}
+void AnnotateUnpublishMemoryRange(const char *file, int line,
+ const volatile void *address,
+ long size){}
+void AnnotatePCQCreate(const char *file, int line,
+ const volatile void *pcq){}
+void AnnotatePCQDestroy(const char *file, int line,
+ const volatile void *pcq){}
+void AnnotatePCQPut(const char *file, int line,
+ const volatile void *pcq){}
+void AnnotatePCQGet(const char *file, int line,
+ const volatile void *pcq){}
+void AnnotateNewMemory(const char *file, int line,
+ const volatile void *mem,
+ long size){}
+void AnnotateExpectRace(const char *file, int line,
+ const volatile void *mem,
+ const char *description){}
+void AnnotateBenignRace(const char *file, int line,
+ const volatile void *mem,
+ const char *description){}
+void AnnotateBenignRaceSized(const char *file, int line,
+ const volatile void *mem,
+ long size,
+ const char *description) {}
+void AnnotateMutexIsUsedAsCondVar(const char *file, int line,
+ const volatile void *mu){}
+void AnnotateTraceMemory(const char *file, int line,
+ const volatile void *arg){}
+void AnnotateThreadName(const char *file, int line,
+ const char *name){}
+void AnnotateIgnoreReadsBegin(const char *file, int line){}
+void AnnotateIgnoreReadsEnd(const char *file, int line){}
+void AnnotateIgnoreWritesBegin(const char *file, int line){}
+void AnnotateIgnoreWritesEnd(const char *file, int line){}
+void AnnotateIgnoreSyncBegin(const char *file, int line){}
+void AnnotateIgnoreSyncEnd(const char *file, int line){}
+void AnnotateEnableRaceDetection(const char *file, int line, int enable){}
+void AnnotateNoOp(const char *file, int line,
+ const volatile void *arg){}
+void AnnotateFlushState(const char *file, int line){}
+
+static int GetRunningOnValgrind(void) {
+#ifdef RUNNING_ON_VALGRIND
+ if (RUNNING_ON_VALGRIND) return 1;
+#endif
+
+#ifndef _MSC_VER
+ const char *running_on_valgrind_str = getenv("RUNNING_ON_VALGRIND");
+ if (running_on_valgrind_str) {
+ return strcmp(running_on_valgrind_str, "0") != 0;
+ }
+#else
+ /* Visual Studio issues warnings if we use getenv,
+ * so we use GetEnvironmentVariableA instead.
+ */
+ char value[100] = "1";
+ int res = GetEnvironmentVariableA("RUNNING_ON_VALGRIND",
+ value, sizeof(value));
+ /* value will remain "1" if res == 0 or res >= sizeof(value). The latter
+ * can happen only if the given value is long, in this case it can't be "0".
+ */
+ if (res > 0 && !strcmp(value, "0"))
+ return 1;
+#endif
+ return 0;
+}
+
+/* See the comments in dynamic_annotations.h */
+int RunningOnValgrind(void) {
+ static volatile int running_on_valgrind = -1;
+ /* C doesn't have thread-safe initialization of statics, and we
+ don't want to depend on pthread_once here, so hack it. */
+ int local_running_on_valgrind = running_on_valgrind;
+ if (local_running_on_valgrind == -1)
+ running_on_valgrind = local_running_on_valgrind = GetRunningOnValgrind();
+ return local_running_on_valgrind;
+}
+
+#endif /* DYNAMIC_ANNOTATIONS_ENABLED == 1 */
diff --git a/contrib/tools/python3/src/Python/dynload_shlib.c b/contrib/tools/python3/src/Python/dynload_shlib.c
new file mode 100644
index 00000000000..23828898d35
--- /dev/null
+++ b/contrib/tools/python3/src/Python/dynload_shlib.c
@@ -0,0 +1,133 @@
+
+/* Support for dynamic loading of extension modules */
+
+#include "Python.h"
+#include "pycore_interp.h" // _PyInterpreterState.dlopenflags
+#include "pycore_pystate.h" // _PyInterpreterState_GET()
+#include "importdl.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if defined(__NetBSD__)
+#include <sys/param.h>
+#if (NetBSD < 199712)
+#include <nlist.h>
+#include <link.h>
+#define dlerror() "error in dynamic linking"
+#endif
+#endif /* NetBSD */
+
+#ifdef HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#if (defined(__OpenBSD__) || defined(__NetBSD__)) && !defined(__ELF__)
+#define LEAD_UNDERSCORE "_"
+#else
+#define LEAD_UNDERSCORE ""
+#endif
+
+/* The .so extension module ABI tag, supplied by the Makefile via
+ Makefile.pre.in and configure. This is used to discriminate between
+ incompatible .so files so that extensions for different Python builds can
+ live in the same directory. E.g. foomodule.cpython-32.so
+*/
+
+const char *_PyImport_DynLoadFiletab[] = {
+#ifdef __CYGWIN__
+ ".dll",
+#else /* !__CYGWIN__ */
+ "." SOABI ".so",
+#ifdef ALT_SOABI
+ "." ALT_SOABI ".so",
+#endif
+ ".abi" PYTHON_ABI_STRING ".so",
+ ".so",
+#endif /* __CYGWIN__ */
+ NULL,
+};
+
+static struct {
+ dev_t dev;
+ ino_t ino;
+ void *handle;
+} handles[128];
+static int nhandles = 0;
+
+
+dl_funcptr
+_PyImport_FindSharedFuncptr(const char *prefix,
+ const char *shortname,
+ const char *pathname, FILE *fp)
+{
+ dl_funcptr p;
+ void *handle;
+ char funcname[258];
+ char pathbuf[260];
+ int dlopenflags=0;
+
+ if (strchr(pathname, '/') == NULL) {
+ /* Prefix bare filename with "./" */
+ PyOS_snprintf(pathbuf, sizeof(pathbuf), "./%-.255s", pathname);
+ pathname = pathbuf;
+ }
+
+ PyOS_snprintf(funcname, sizeof(funcname),
+ LEAD_UNDERSCORE "%.20s_%.200s", prefix, shortname);
+
+ if (fp != NULL) {
+ int i;
+ struct _Py_stat_struct status;
+ if (_Py_fstat(fileno(fp), &status) == -1)
+ return NULL;
+ for (i = 0; i < nhandles; i++) {
+ if (status.st_dev == handles[i].dev &&
+ status.st_ino == handles[i].ino) {
+ p = (dl_funcptr) dlsym(handles[i].handle,
+ funcname);
+ return p;
+ }
+ }
+ if (nhandles < 128) {
+ handles[nhandles].dev = status.st_dev;
+ handles[nhandles].ino = status.st_ino;
+ }
+ }
+
+ dlopenflags = _PyInterpreterState_GET()->dlopenflags;
+
+ handle = dlopen(pathname, dlopenflags);
+
+ if (handle == NULL) {
+ PyObject *mod_name;
+ PyObject *path;
+ PyObject *error_ob;
+ const char *error = dlerror();
+ if (error == NULL)
+ error = "unknown dlopen() error";
+ error_ob = PyUnicode_DecodeLocale(error, "surrogateescape");
+ if (error_ob == NULL)
+ return NULL;
+ mod_name = PyUnicode_FromString(shortname);
+ if (mod_name == NULL) {
+ Py_DECREF(error_ob);
+ return NULL;
+ }
+ path = PyUnicode_DecodeFSDefault(pathname);
+ if (path == NULL) {
+ Py_DECREF(error_ob);
+ Py_DECREF(mod_name);
+ return NULL;
+ }
+ PyErr_SetImportError(error_ob, mod_name, path);
+ Py_DECREF(error_ob);
+ Py_DECREF(mod_name);
+ Py_DECREF(path);
+ return NULL;
+ }
+ if (fp != NULL && nhandles < 128)
+ handles[nhandles++].handle = handle;
+ p = (dl_funcptr) dlsym(handle, funcname);
+ return p;
+}
diff --git a/contrib/tools/python3/src/Python/dynload_win.c b/contrib/tools/python3/src/Python/dynload_win.c
new file mode 100644
index 00000000000..81787e5f22a
--- /dev/null
+++ b/contrib/tools/python3/src/Python/dynload_win.c
@@ -0,0 +1,285 @@
+
+/* Support for dynamic loading of extension modules */
+
+#include "Python.h"
+
+#ifdef HAVE_DIRECT_H
+#include <direct.h>
+#endif
+#include <ctype.h>
+
+#include "importdl.h"
+#include "patchlevel.h"
+#include <windows.h>
+
+#ifdef _DEBUG
+#define PYD_DEBUG_SUFFIX "_d"
+#else
+#define PYD_DEBUG_SUFFIX ""
+#endif
+
+#ifdef PYD_PLATFORM_TAG
+#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) "-" PYD_PLATFORM_TAG ".pyd"
+#else
+#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) ".pyd"
+#endif
+
+#define PYD_UNTAGGED_SUFFIX PYD_DEBUG_SUFFIX ".pyd"
+
+const char *_PyImport_DynLoadFiletab[] = {
+ PYD_TAGGED_SUFFIX,
+ PYD_UNTAGGED_SUFFIX,
+ NULL
+};
+
+/* Function to return the name of the "python" DLL that the supplied module
+ directly imports. Looks through the list of imported modules and
+ returns the first entry that starts with "python" (case sensitive) and
+ is followed by nothing but numbers until the separator (period).
+
+ Returns a pointer to the import name, or NULL if no matching name was
+ located.
+
+ This function parses through the PE header for the module as loaded in
+ memory by the system loader. The PE header is accessed as documented by
+ Microsoft in the MSDN PE and COFF specification (2/99), and handles
+ both PE32 and PE32+. It only worries about the direct import table and
+ not the delay load import table since it's unlikely an extension is
+ going to be delay loading Python (after all, it's already loaded).
+
+ If any magic values are not found (e.g., the PE header or optional
+ header magic), then this function simply returns NULL. */
+
+#define DWORD_AT(mem) (*(DWORD *)(mem))
+#define WORD_AT(mem) (*(WORD *)(mem))
+
+static char *GetPythonImport (HINSTANCE hModule)
+{
+ unsigned char *dllbase, *import_data, *import_name;
+ DWORD pe_offset, opt_offset;
+ WORD opt_magic;
+ int num_dict_off, import_off;
+
+ /* Safety check input */
+ if (hModule == NULL) {
+ return NULL;
+ }
+
+ /* Module instance is also the base load address. First portion of
+ memory is the MS-DOS loader, which holds the offset to the PE
+ header (from the load base) at 0x3C */
+ dllbase = (unsigned char *)hModule;
+ pe_offset = DWORD_AT(dllbase + 0x3C);
+
+ /* The PE signature must be "PE\0\0" */
+ if (memcmp(dllbase+pe_offset,"PE\0\0",4)) {
+ return NULL;
+ }
+
+ /* Following the PE signature is the standard COFF header (20
+ bytes) and then the optional header. The optional header starts
+ with a magic value of 0x10B for PE32 or 0x20B for PE32+ (PE32+
+ uses 64-bits for some fields). It might also be 0x107 for a ROM
+ image, but we don't process that here.
+
+ The optional header ends with a data dictionary that directly
+ points to certain types of data, among them the import entries
+ (in the second table entry). Based on the header type, we
+ determine offsets for the data dictionary count and the entry
+ within the dictionary pointing to the imports. */
+
+ opt_offset = pe_offset + 4 + 20;
+ opt_magic = WORD_AT(dllbase+opt_offset);
+ if (opt_magic == 0x10B) {
+ /* PE32 */
+ num_dict_off = 92;
+ import_off = 104;
+ } else if (opt_magic == 0x20B) {
+ /* PE32+ */
+ num_dict_off = 108;
+ import_off = 120;
+ } else {
+ /* Unsupported */
+ return NULL;
+ }
+
+ /* Now if an import table exists, offset to it and walk the list of
+ imports. The import table is an array (ending when an entry has
+ empty values) of structures (20 bytes each), which contains (at
+ offset 12) a relative address (to the module base) at which a
+ string constant holding the import name is located. */
+
+ if (DWORD_AT(dllbase + opt_offset + num_dict_off) >= 2) {
+ /* We have at least 2 tables - the import table is the second
+ one. But still it may be that the table size is zero */
+ if (0 == DWORD_AT(dllbase + opt_offset + import_off + sizeof(DWORD)))
+ return NULL;
+ import_data = dllbase + DWORD_AT(dllbase +
+ opt_offset +
+ import_off);
+ while (DWORD_AT(import_data)) {
+ import_name = dllbase + DWORD_AT(import_data+12);
+ if (strlen(import_name) >= 6 &&
+ !strncmp(import_name,"python",6)) {
+ char *pch;
+
+#ifndef _DEBUG
+ /* In a release version, don't claim that python3.dll is
+ a Python DLL. */
+ if (strcmp(import_name, "python3.dll") == 0) {
+ import_data += 20;
+ continue;
+ }
+#endif
+
+ /* Ensure python prefix is followed only
+ by numbers to the end of the basename */
+ pch = import_name + 6;
+#ifdef _DEBUG
+ while (*pch && pch[0] != '_' && pch[1] != 'd' && pch[2] != '.') {
+#else
+ while (*pch && *pch != '.') {
+#endif
+ if (*pch >= '0' && *pch <= '9') {
+ pch++;
+ } else {
+ pch = NULL;
+ break;
+ }
+ }
+
+ if (pch) {
+ /* Found it - return the name */
+ return import_name;
+ }
+ }
+ import_data += 20;
+ }
+ }
+
+ return NULL;
+}
+
+dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix,
+ const char *shortname,
+ PyObject *pathname, FILE *fp)
+{
+ dl_funcptr p;
+ char funcname[258], *import_python;
+ const wchar_t *wpathname;
+
+ _Py_CheckPython3();
+
+_Py_COMP_DIAG_PUSH
+_Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ wpathname = _PyUnicode_AsUnicode(pathname);
+_Py_COMP_DIAG_POP
+ if (wpathname == NULL)
+ return NULL;
+
+ PyOS_snprintf(funcname, sizeof(funcname), "%.20s_%.200s", prefix, shortname);
+
+ {
+ HINSTANCE hDLL = NULL;
+ unsigned int old_mode;
+
+ /* Don't display a message box when Python can't load a DLL */
+ old_mode = SetErrorMode(SEM_FAILCRITICALERRORS);
+
+ /* bpo-36085: We use LoadLibraryEx with restricted search paths
+ to avoid DLL preloading attacks and enable use of the
+ AddDllDirectory function. We add SEARCH_DLL_LOAD_DIR to
+ ensure DLLs adjacent to the PYD are preferred. */
+ Py_BEGIN_ALLOW_THREADS
+ hDLL = LoadLibraryExW(wpathname, NULL,
+ LOAD_LIBRARY_SEARCH_DEFAULT_DIRS |
+ LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
+ Py_END_ALLOW_THREADS
+
+ /* restore old error mode settings */
+ SetErrorMode(old_mode);
+
+ if (hDLL==NULL){
+ PyObject *message;
+ unsigned int errorCode;
+
+ /* Get an error string from Win32 error code */
+ wchar_t theInfo[256]; /* Pointer to error text
+ from system */
+ int theLength; /* Length of error text */
+
+ errorCode = GetLastError();
+
+ theLength = FormatMessageW(
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS, /* flags */
+ NULL, /* message source */
+ errorCode, /* the message (error) ID */
+ MAKELANGID(LANG_NEUTRAL,
+ SUBLANG_DEFAULT),
+ /* Default language */
+ theInfo, /* the buffer */
+ sizeof(theInfo) / sizeof(wchar_t), /* size in wchars */
+ NULL); /* no additional format args. */
+
+ /* Problem: could not get the error message.
+ This should not happen if called correctly. */
+ if (theLength == 0) {
+ message = PyUnicode_FromFormat(
+ "DLL load failed with error code %u while importing %s",
+ errorCode, shortname);
+ } else {
+ /* For some reason a \r\n
+ is appended to the text */
+ if (theLength >= 2 &&
+ theInfo[theLength-2] == '\r' &&
+ theInfo[theLength-1] == '\n') {
+ theLength -= 2;
+ theInfo[theLength] = '\0';
+ }
+ message = PyUnicode_FromFormat(
+ "DLL load failed while importing %s: ", shortname);
+
+ PyUnicode_AppendAndDel(&message,
+ PyUnicode_FromWideChar(
+ theInfo,
+ theLength));
+ }
+ if (message != NULL) {
+ PyObject *shortname_obj = PyUnicode_FromString(shortname);
+ PyErr_SetImportError(message, shortname_obj, pathname);
+ Py_XDECREF(shortname_obj);
+ Py_DECREF(message);
+ }
+ return NULL;
+ } else {
+ char buffer[256];
+
+ PyOS_snprintf(buffer, sizeof(buffer),
+#ifdef _DEBUG
+ "python%d%d_d.dll",
+#else
+ "python%d%d.dll",
+#endif
+ PY_MAJOR_VERSION,PY_MINOR_VERSION);
+ import_python = GetPythonImport(hDLL);
+
+ if (import_python &&
+ _stricmp(buffer,import_python)) {
+ PyErr_Format(PyExc_ImportError,
+ "Module use of %.150s conflicts "
+ "with this version of Python.",
+ import_python);
+ Py_BEGIN_ALLOW_THREADS
+ FreeLibrary(hDLL);
+ Py_END_ALLOW_THREADS
+ return NULL;
+ }
+ }
+ Py_BEGIN_ALLOW_THREADS
+ p = GetProcAddress(hDLL, funcname);
+ Py_END_ALLOW_THREADS
+ }
+
+ return p;
+}
diff --git a/contrib/tools/python3/src/Python/errors.c b/contrib/tools/python3/src/Python/errors.c
new file mode 100644
index 00000000000..79278764cc5
--- /dev/null
+++ b/contrib/tools/python3/src/Python/errors.c
@@ -0,0 +1,1742 @@
+
+/* Error handling */
+
+#include "Python.h"
+#include "pycore_initconfig.h"
+#include "pycore_object.h" // _PyType_GetQualName
+#include "pycore_pyerrors.h"
+#include "pycore_pystate.h" // _PyThreadState_GET()
+#include "pycore_sysmodule.h"
+#include "pycore_traceback.h"
+
+#ifndef __STDC__
+#ifndef MS_WINDOWS
+extern char *strerror(int);
+#endif
+#endif
+
+#ifdef MS_WINDOWS
+#include <windows.h>
+#include <winbase.h>
+#endif
+
+#include <ctype.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_Py_IDENTIFIER(__module__);
+_Py_IDENTIFIER(builtins);
+_Py_IDENTIFIER(stderr);
+_Py_IDENTIFIER(flush);
+
+/* Forward declarations */
+static PyObject *
+_PyErr_FormatV(PyThreadState *tstate, PyObject *exception,
+ const char *format, va_list vargs);
+
+
+void
+_PyErr_Restore(PyThreadState *tstate, PyObject *type, PyObject *value,
+ PyObject *traceback)
+{
+ PyObject *oldtype, *oldvalue, *oldtraceback;
+
+ if (traceback != NULL && !PyTraceBack_Check(traceback)) {
+ /* XXX Should never happen -- fatal error instead? */
+ /* Well, it could be None. */
+ Py_DECREF(traceback);
+ traceback = NULL;
+ }
+
+ /* Save these in locals to safeguard against recursive
+ invocation through Py_XDECREF */
+ oldtype = tstate->curexc_type;
+ oldvalue = tstate->curexc_value;
+ oldtraceback = tstate->curexc_traceback;
+
+ tstate->curexc_type = type;
+ tstate->curexc_value = value;
+ tstate->curexc_traceback = traceback;
+
+ Py_XDECREF(oldtype);
+ Py_XDECREF(oldvalue);
+ Py_XDECREF(oldtraceback);
+}
+
+void
+PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ _PyErr_Restore(tstate, type, value, traceback);
+}
+
+
+_PyErr_StackItem *
+_PyErr_GetTopmostException(PyThreadState *tstate)
+{
+ _PyErr_StackItem *exc_info = tstate->exc_info;
+ while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) &&
+ exc_info->previous_item != NULL)
+ {
+ exc_info = exc_info->previous_item;
+ }
+ return exc_info;
+}
+
+static PyObject*
+_PyErr_CreateException(PyObject *exception_type, PyObject *value)
+{
+ PyObject *exc;
+
+ if (value == NULL || value == Py_None) {
+ exc = _PyObject_CallNoArg(exception_type);
+ }
+ else if (PyTuple_Check(value)) {
+ exc = PyObject_Call(exception_type, value, NULL);
+ }
+ else {
+ exc = PyObject_CallOneArg(exception_type, value);
+ }
+
+ if (exc != NULL && !PyExceptionInstance_Check(exc)) {
+ PyErr_Format(PyExc_TypeError,
+ "calling %R should have returned an instance of "
+ "BaseException, not %s",
+ exception_type, Py_TYPE(exc)->tp_name);
+ Py_CLEAR(exc);
+ }
+
+ return exc;
+}
+
+void
+_PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value)
+{
+ PyObject *exc_value;
+ PyObject *tb = NULL;
+
+ if (exception != NULL &&
+ !PyExceptionClass_Check(exception)) {
+ _PyErr_Format(tstate, PyExc_SystemError,
+ "_PyErr_SetObject: "
+ "exception %R is not a BaseException subclass",
+ exception);
+ return;
+ }
+
+ Py_XINCREF(value);
+ exc_value = _PyErr_GetTopmostException(tstate)->exc_value;
+ if (exc_value != NULL && exc_value != Py_None) {
+ /* Implicit exception chaining */
+ Py_INCREF(exc_value);
+ if (value == NULL || !PyExceptionInstance_Check(value)) {
+ /* We must normalize the value right now */
+ PyObject *fixed_value;
+
+ /* Issue #23571: functions must not be called with an
+ exception set */
+ _PyErr_Clear(tstate);
+
+ fixed_value = _PyErr_CreateException(exception, value);
+ Py_XDECREF(value);
+ if (fixed_value == NULL) {
+ Py_DECREF(exc_value);
+ return;
+ }
+
+ value = fixed_value;
+ }
+
+ /* Avoid creating new reference cycles through the
+ context chain, while taking care not to hang on
+ pre-existing ones.
+ This is O(chain length) but context chains are
+ usually very short. Sensitive readers may try
+ to inline the call to PyException_GetContext. */
+ if (exc_value != value) {
+ PyObject *o = exc_value, *context;
+ PyObject *slow_o = o; /* Floyd's cycle detection algo */
+ int slow_update_toggle = 0;
+ while ((context = PyException_GetContext(o))) {
+ Py_DECREF(context);
+ if (context == value) {
+ PyException_SetContext(o, NULL);
+ break;
+ }
+ o = context;
+ if (o == slow_o) {
+ /* pre-existing cycle - all exceptions on the
+ path were visited and checked. */
+ break;
+ }
+ if (slow_update_toggle) {
+ slow_o = PyException_GetContext(slow_o);
+ Py_DECREF(slow_o);
+ }
+ slow_update_toggle = !slow_update_toggle;
+ }
+ PyException_SetContext(value, exc_value);
+ }
+ else {
+ Py_DECREF(exc_value);
+ }
+ }
+ if (value != NULL && PyExceptionInstance_Check(value))
+ tb = PyException_GetTraceback(value);
+ Py_XINCREF(exception);
+ _PyErr_Restore(tstate, exception, value, tb);
+}
+
+void
+PyErr_SetObject(PyObject *exception, PyObject *value)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ _PyErr_SetObject(tstate, exception, value);
+}
+
+/* Set a key error with the specified argument, wrapping it in a
+ * tuple automatically so that tuple keys are not unpacked as the
+ * exception arguments. */
+void
+_PyErr_SetKeyError(PyObject *arg)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyObject *tup = PyTuple_Pack(1, arg);
+ if (!tup) {
+ /* caller will expect error to be set anyway */
+ return;
+ }
+ _PyErr_SetObject(tstate, PyExc_KeyError, tup);
+ Py_DECREF(tup);
+}
+
+void
+_PyErr_SetNone(PyThreadState *tstate, PyObject *exception)
+{
+ _PyErr_SetObject(tstate, exception, (PyObject *)NULL);
+}
+
+
+void
+PyErr_SetNone(PyObject *exception)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ _PyErr_SetNone(tstate, exception);
+}
+
+
+void
+_PyErr_SetString(PyThreadState *tstate, PyObject *exception,
+ const char *string)
+{
+ PyObject *value = PyUnicode_FromString(string);
+ _PyErr_SetObject(tstate, exception, value);
+ Py_XDECREF(value);
+}
+
+void
+PyErr_SetString(PyObject *exception, const char *string)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ _PyErr_SetString(tstate, exception, string);
+}
+
+
+PyObject* _Py_HOT_FUNCTION
+PyErr_Occurred(void)
+{
+ /* The caller must hold the GIL. */
+ assert(PyGILState_Check());
+
+ PyThreadState *tstate = _PyThreadState_GET();
+ return _PyErr_Occurred(tstate);
+}
+
+
+int
+PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc)
+{
+ if (err == NULL || exc == NULL) {
+ /* maybe caused by "import exceptions" that failed early on */
+ return 0;
+ }
+ if (PyTuple_Check(exc)) {
+ Py_ssize_t i, n;
+ n = PyTuple_Size(exc);
+ for (i = 0; i < n; i++) {
+ /* Test recursively */
+ if (PyErr_GivenExceptionMatches(
+ err, PyTuple_GET_ITEM(exc, i)))
+ {
+ return 1;
+ }
+ }
+ return 0;
+ }
+ /* err might be an instance, so check its class. */
+ if (PyExceptionInstance_Check(err))
+ err = PyExceptionInstance_Class(err);
+
+ if (PyExceptionClass_Check(err) && PyExceptionClass_Check(exc)) {
+ return PyType_IsSubtype((PyTypeObject *)err, (PyTypeObject *)exc);
+ }
+
+ return err == exc;
+}
+
+
+int
+_PyErr_ExceptionMatches(PyThreadState *tstate, PyObject *exc)
+{
+ return PyErr_GivenExceptionMatches(_PyErr_Occurred(tstate), exc);
+}
+
+
+int
+PyErr_ExceptionMatches(PyObject *exc)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ return _PyErr_ExceptionMatches(tstate, exc);
+}
+
+
+#ifndef Py_NORMALIZE_RECURSION_LIMIT
+#define Py_NORMALIZE_RECURSION_LIMIT 32
+#endif
+
+/* Used in many places to normalize a raised exception, including in
+ eval_code2(), do_raise(), and PyErr_Print()
+
+ XXX: should PyErr_NormalizeException() also call
+ PyException_SetTraceback() with the resulting value and tb?
+*/
+void
+_PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc,
+ PyObject **val, PyObject **tb)
+{
+ int recursion_depth = 0;
+ tstate->overflowed++;
+ PyObject *type, *value, *initial_tb;
+
+ restart:
+ type = *exc;
+ if (type == NULL) {
+ /* There was no exception, so nothing to do. */
+ tstate->overflowed--;
+ return;
+ }
+
+ value = *val;
+ /* If PyErr_SetNone() was used, the value will have been actually
+ set to NULL.
+ */
+ if (!value) {
+ value = Py_None;
+ Py_INCREF(value);
+ }
+
+ /* Normalize the exception so that if the type is a class, the
+ value will be an instance.
+ */
+ if (PyExceptionClass_Check(type)) {
+ PyObject *inclass = NULL;
+ int is_subclass = 0;
+
+ if (PyExceptionInstance_Check(value)) {
+ inclass = PyExceptionInstance_Class(value);
+ is_subclass = PyObject_IsSubclass(inclass, type);
+ if (is_subclass < 0) {
+ goto error;
+ }
+ }
+
+ /* If the value was not an instance, or is not an instance
+ whose class is (or is derived from) type, then use the
+ value as an argument to instantiation of the type
+ class.
+ */
+ if (!is_subclass) {
+ PyObject *fixed_value = _PyErr_CreateException(type, value);
+ if (fixed_value == NULL) {
+ goto error;
+ }
+ Py_DECREF(value);
+ value = fixed_value;
+ }
+ /* If the class of the instance doesn't exactly match the
+ class of the type, believe the instance.
+ */
+ else if (inclass != type) {
+ Py_INCREF(inclass);
+ Py_DECREF(type);
+ type = inclass;
+ }
+ }
+ *exc = type;
+ *val = value;
+ tstate->overflowed--;
+ return;
+
+ error:
+ Py_DECREF(type);
+ Py_DECREF(value);
+ recursion_depth++;
+ if (recursion_depth == Py_NORMALIZE_RECURSION_LIMIT) {
+ _PyErr_SetString(tstate, PyExc_RecursionError,
+ "maximum recursion depth exceeded "
+ "while normalizing an exception");
+ }
+ /* If the new exception doesn't set a traceback and the old
+ exception had a traceback, use the old traceback for the
+ new exception. It's better than nothing.
+ */
+ initial_tb = *tb;
+ _PyErr_Fetch(tstate, exc, val, tb);
+ assert(*exc != NULL);
+ if (initial_tb != NULL) {
+ if (*tb == NULL)
+ *tb = initial_tb;
+ else
+ Py_DECREF(initial_tb);
+ }
+ /* Abort when Py_NORMALIZE_RECURSION_LIMIT has been exceeded, and the
+ corresponding RecursionError could not be normalized, and the
+ MemoryError raised when normalize this RecursionError could not be
+ normalized. */
+ if (recursion_depth >= Py_NORMALIZE_RECURSION_LIMIT + 2) {
+ if (PyErr_GivenExceptionMatches(*exc, PyExc_MemoryError)) {
+ Py_FatalError("Cannot recover from MemoryErrors "
+ "while normalizing exceptions.");
+ }
+ else {
+ Py_FatalError("Cannot recover from the recursive normalization "
+ "of an exception.");
+ }
+ }
+ goto restart;
+}
+
+
+void
+PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ _PyErr_NormalizeException(tstate, exc, val, tb);
+}
+
+
+void
+_PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, PyObject **p_value,
+ PyObject **p_traceback)
+{
+ *p_type = tstate->curexc_type;
+ *p_value = tstate->curexc_value;
+ *p_traceback = tstate->curexc_traceback;
+
+ tstate->curexc_type = NULL;
+ tstate->curexc_value = NULL;
+ tstate->curexc_traceback = NULL;
+}
+
+
+void
+PyErr_Fetch(PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ _PyErr_Fetch(tstate, p_type, p_value, p_traceback);
+}
+
+
+void
+_PyErr_Clear(PyThreadState *tstate)
+{
+ _PyErr_Restore(tstate, NULL, NULL, NULL);
+}
+
+
+void
+PyErr_Clear(void)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ _PyErr_Clear(tstate);
+}
+
+
+void
+_PyErr_GetExcInfo(PyThreadState *tstate,
+ PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
+{
+ _PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate);
+ *p_type = exc_info->exc_type;
+ *p_value = exc_info->exc_value;
+ *p_traceback = exc_info->exc_traceback;
+
+ Py_XINCREF(*p_type);
+ Py_XINCREF(*p_value);
+ Py_XINCREF(*p_traceback);
+}
+
+
+void
+PyErr_GetExcInfo(PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ _PyErr_GetExcInfo(tstate, p_type, p_value, p_traceback);
+}
+
+void
+PyErr_SetExcInfo(PyObject *p_type, PyObject *p_value, PyObject *p_traceback)
+{
+ PyObject *oldtype, *oldvalue, *oldtraceback;
+ PyThreadState *tstate = _PyThreadState_GET();
+
+ oldtype = tstate->exc_info->exc_type;
+ oldvalue = tstate->exc_info->exc_value;
+ oldtraceback = tstate->exc_info->exc_traceback;
+
+ tstate->exc_info->exc_type = p_type;
+ tstate->exc_info->exc_value = p_value;
+ tstate->exc_info->exc_traceback = p_traceback;
+
+ Py_XDECREF(oldtype);
+ Py_XDECREF(oldvalue);
+ Py_XDECREF(oldtraceback);
+}
+
+/* Like PyErr_Restore(), but if an exception is already set,
+ set the context associated with it.
+
+ The caller is responsible for ensuring that this call won't create
+ any cycles in the exception context chain. */
+void
+_PyErr_ChainExceptions(PyObject *exc, PyObject *val, PyObject *tb)
+{
+ if (exc == NULL)
+ return;
+
+ PyThreadState *tstate = _PyThreadState_GET();
+
+ if (!PyExceptionClass_Check(exc)) {
+ _PyErr_Format(tstate, PyExc_SystemError,
+ "_PyErr_ChainExceptions: "
+ "exception %R is not a BaseException subclass",
+ exc);
+ return;
+ }
+
+ if (_PyErr_Occurred(tstate)) {
+ PyObject *exc2, *val2, *tb2;
+ _PyErr_Fetch(tstate, &exc2, &val2, &tb2);
+ _PyErr_NormalizeException(tstate, &exc, &val, &tb);
+ if (tb != NULL) {
+ PyException_SetTraceback(val, tb);
+ Py_DECREF(tb);
+ }
+ Py_DECREF(exc);
+ _PyErr_NormalizeException(tstate, &exc2, &val2, &tb2);
+ PyException_SetContext(val2, val);
+ _PyErr_Restore(tstate, exc2, val2, tb2);
+ }
+ else {
+ _PyErr_Restore(tstate, exc, val, tb);
+ }
+}
+
+/* Set the currently set exception's context to the given exception.
+
+ If the provided exc_info is NULL, then the current Python thread state's
+ exc_info will be used for the context instead.
+
+ This function can only be called when _PyErr_Occurred() is true.
+ Also, this function won't create any cycles in the exception context
+ chain to the extent that _PyErr_SetObject ensures this. */
+void
+_PyErr_ChainStackItem(_PyErr_StackItem *exc_info)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ assert(_PyErr_Occurred(tstate));
+
+ int exc_info_given;
+ if (exc_info == NULL) {
+ exc_info_given = 0;
+ exc_info = tstate->exc_info;
+ } else {
+ exc_info_given = 1;
+ }
+ if (exc_info->exc_type == NULL || exc_info->exc_type == Py_None) {
+ return;
+ }
+
+ _PyErr_StackItem *saved_exc_info;
+ if (exc_info_given) {
+ /* Temporarily set the thread state's exc_info since this is what
+ _PyErr_SetObject uses for implicit exception chaining. */
+ saved_exc_info = tstate->exc_info;
+ tstate->exc_info = exc_info;
+ }
+
+ PyObject *exc, *val, *tb;
+ _PyErr_Fetch(tstate, &exc, &val, &tb);
+
+ PyObject *exc2, *val2, *tb2;
+ exc2 = exc_info->exc_type;
+ val2 = exc_info->exc_value;
+ tb2 = exc_info->exc_traceback;
+ _PyErr_NormalizeException(tstate, &exc2, &val2, &tb2);
+ if (tb2 != NULL) {
+ PyException_SetTraceback(val2, tb2);
+ }
+
+ /* _PyErr_SetObject sets the context from PyThreadState. */
+ _PyErr_SetObject(tstate, exc, val);
+ Py_DECREF(exc); // since _PyErr_Occurred was true
+ Py_XDECREF(val);
+ Py_XDECREF(tb);
+
+ if (exc_info_given) {
+ tstate->exc_info = saved_exc_info;
+ }
+}
+
+static PyObject *
+_PyErr_FormatVFromCause(PyThreadState *tstate, PyObject *exception,
+ const char *format, va_list vargs)
+{
+ PyObject *exc, *val, *val2, *tb;
+
+ assert(_PyErr_Occurred(tstate));
+ _PyErr_Fetch(tstate, &exc, &val, &tb);
+ _PyErr_NormalizeException(tstate, &exc, &val, &tb);
+ if (tb != NULL) {
+ PyException_SetTraceback(val, tb);
+ Py_DECREF(tb);
+ }
+ Py_DECREF(exc);
+ assert(!_PyErr_Occurred(tstate));
+
+ _PyErr_FormatV(tstate, exception, format, vargs);
+
+ _PyErr_Fetch(tstate, &exc, &val2, &tb);
+ _PyErr_NormalizeException(tstate, &exc, &val2, &tb);
+ Py_INCREF(val);
+ PyException_SetCause(val2, val);
+ PyException_SetContext(val2, val);
+ _PyErr_Restore(tstate, exc, val2, tb);
+
+ return NULL;
+}
+
+PyObject *
+_PyErr_FormatFromCauseTstate(PyThreadState *tstate, PyObject *exception,
+ const char *format, ...)
+{
+ va_list vargs;
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, format);
+#else
+ va_start(vargs);
+#endif
+ _PyErr_FormatVFromCause(tstate, exception, format, vargs);
+ va_end(vargs);
+ return NULL;
+}
+
+PyObject *
+_PyErr_FormatFromCause(PyObject *exception, const char *format, ...)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ va_list vargs;
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, format);
+#else
+ va_start(vargs);
+#endif
+ _PyErr_FormatVFromCause(tstate, exception, format, vargs);
+ va_end(vargs);
+ return NULL;
+}
+
+/* Convenience functions to set a type error exception and return 0 */
+
+int
+PyErr_BadArgument(void)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ _PyErr_SetString(tstate, PyExc_TypeError,
+ "bad argument type for built-in operation");
+ return 0;
+}
+
+PyObject *
+_PyErr_NoMemory(PyThreadState *tstate)
+{
+ if (Py_IS_TYPE(PyExc_MemoryError, NULL)) {
+ /* PyErr_NoMemory() has been called before PyExc_MemoryError has been
+ initialized by _PyExc_Init() */
+ Py_FatalError("Out of memory and PyExc_MemoryError is not "
+ "initialized yet");
+ }
+ _PyErr_SetNone(tstate, PyExc_MemoryError);
+ return NULL;
+}
+
+PyObject *
+PyErr_NoMemory(void)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ return _PyErr_NoMemory(tstate);
+}
+
+PyObject *
+PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)
+{
+ return PyErr_SetFromErrnoWithFilenameObjects(exc, filenameObject, NULL);
+}
+
+PyObject *
+PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, PyObject *filenameObject2)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyObject *message;
+ PyObject *v, *args;
+ int i = errno;
+#ifdef MS_WINDOWS
+ WCHAR *s_buf = NULL;
+#endif /* Unix/Windows */
+
+#ifdef EINTR
+ if (i == EINTR && PyErr_CheckSignals())
+ return NULL;
+#endif
+
+#ifndef MS_WINDOWS
+ if (i != 0) {
+ const char *s = strerror(i);
+ message = PyUnicode_DecodeLocale(s, "surrogateescape");
+ }
+ else {
+ /* Sometimes errno didn't get set */
+ message = PyUnicode_FromString("Error");
+ }
+#else
+ if (i == 0)
+ message = PyUnicode_FromString("Error"); /* Sometimes errno didn't get set */
+ else
+ {
+ /* Note that the Win32 errors do not lineup with the
+ errno error. So if the error is in the MSVC error
+ table, we use it, otherwise we assume it really _is_
+ a Win32 error code
+ */
+ if (i > 0 && i < _sys_nerr) {
+ message = PyUnicode_FromString(_sys_errlist[i]);
+ }
+ else {
+ int len = FormatMessageW(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, /* no message source */
+ i,
+ MAKELANGID(LANG_NEUTRAL,
+ SUBLANG_DEFAULT),
+ /* Default language */
+ (LPWSTR) &s_buf,
+ 0, /* size not used */
+ NULL); /* no args */
+ if (len==0) {
+ /* Only ever seen this in out-of-mem
+ situations */
+ s_buf = NULL;
+ message = PyUnicode_FromFormat("Windows Error 0x%x", i);
+ } else {
+ /* remove trailing cr/lf and dots */
+ while (len > 0 && (s_buf[len-1] <= L' ' || s_buf[len-1] == L'.'))
+ s_buf[--len] = L'\0';
+ message = PyUnicode_FromWideChar(s_buf, len);
+ }
+ }
+ }
+#endif /* Unix/Windows */
+
+ if (message == NULL)
+ {
+#ifdef MS_WINDOWS
+ LocalFree(s_buf);
+#endif
+ return NULL;
+ }
+
+ if (filenameObject != NULL) {
+ if (filenameObject2 != NULL)
+ args = Py_BuildValue("(iOOiO)", i, message, filenameObject, 0, filenameObject2);
+ else
+ args = Py_BuildValue("(iOO)", i, message, filenameObject);
+ } else {
+ assert(filenameObject2 == NULL);
+ args = Py_BuildValue("(iO)", i, message);
+ }
+ Py_DECREF(message);
+
+ if (args != NULL) {
+ v = PyObject_Call(exc, args, NULL);
+ Py_DECREF(args);
+ if (v != NULL) {
+ _PyErr_SetObject(tstate, (PyObject *) Py_TYPE(v), v);
+ Py_DECREF(v);
+ }
+ }
+#ifdef MS_WINDOWS
+ LocalFree(s_buf);
+#endif
+ return NULL;
+}
+
+PyObject *
+PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename)
+{
+ PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
+ PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL);
+ Py_XDECREF(name);
+ return result;
+}
+
+#ifdef MS_WINDOWS
+PyObject *
+PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, const Py_UNICODE *filename)
+{
+ PyObject *name = filename ? PyUnicode_FromWideChar(filename, -1) : NULL;
+ PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL);
+ Py_XDECREF(name);
+ return result;
+}
+#endif /* MS_WINDOWS */
+
+PyObject *
+PyErr_SetFromErrno(PyObject *exc)
+{
+ return PyErr_SetFromErrnoWithFilenameObjects(exc, NULL, NULL);
+}
+
+#ifdef MS_WINDOWS
+/* Windows specific error code handling */
+PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(
+ PyObject *exc,
+ int ierr,
+ PyObject *filenameObject)
+{
+ return PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, ierr,
+ filenameObject, NULL);
+}
+
+PyObject *PyErr_SetExcFromWindowsErrWithFilenameObjects(
+ PyObject *exc,
+ int ierr,
+ PyObject *filenameObject,
+ PyObject *filenameObject2)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ int len;
+ WCHAR *s_buf = NULL; /* Free via LocalFree */
+ PyObject *message;
+ PyObject *args, *v;
+
+ DWORD err = (DWORD)ierr;
+ if (err==0) {
+ err = GetLastError();
+ }
+
+ len = FormatMessageW(
+ /* Error API error */
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, /* no message source */
+ err,
+ MAKELANGID(LANG_NEUTRAL,
+ SUBLANG_DEFAULT), /* Default language */
+ (LPWSTR) &s_buf,
+ 0, /* size not used */
+ NULL); /* no args */
+ if (len==0) {
+ /* Only seen this in out of mem situations */
+ message = PyUnicode_FromFormat("Windows Error 0x%x", err);
+ s_buf = NULL;
+ } else {
+ /* remove trailing cr/lf and dots */
+ while (len > 0 && (s_buf[len-1] <= L' ' || s_buf[len-1] == L'.'))
+ s_buf[--len] = L'\0';
+ message = PyUnicode_FromWideChar(s_buf, len);
+ }
+
+ if (message == NULL)
+ {
+ LocalFree(s_buf);
+ return NULL;
+ }
+
+ if (filenameObject == NULL) {
+ assert(filenameObject2 == NULL);
+ filenameObject = filenameObject2 = Py_None;
+ }
+ else if (filenameObject2 == NULL)
+ filenameObject2 = Py_None;
+ /* This is the constructor signature for OSError.
+ The POSIX translation will be figured out by the constructor. */
+ args = Py_BuildValue("(iOOiO)", 0, message, filenameObject, err, filenameObject2);
+ Py_DECREF(message);
+
+ if (args != NULL) {
+ v = PyObject_Call(exc, args, NULL);
+ Py_DECREF(args);
+ if (v != NULL) {
+ _PyErr_SetObject(tstate, (PyObject *) Py_TYPE(v), v);
+ Py_DECREF(v);
+ }
+ }
+ LocalFree(s_buf);
+ return NULL;
+}
+
+PyObject *PyErr_SetExcFromWindowsErrWithFilename(
+ PyObject *exc,
+ int ierr,
+ const char *filename)
+{
+ PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
+ PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc,
+ ierr,
+ name,
+ NULL);
+ Py_XDECREF(name);
+ return ret;
+}
+
+PyObject *PyErr_SetExcFromWindowsErrWithUnicodeFilename(
+ PyObject *exc,
+ int ierr,
+ const Py_UNICODE *filename)
+{
+ PyObject *name = filename ? PyUnicode_FromWideChar(filename, -1) : NULL;
+ PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc,
+ ierr,
+ name,
+ NULL);
+ Py_XDECREF(name);
+ return ret;
+}
+
+PyObject *PyErr_SetExcFromWindowsErr(PyObject *exc, int ierr)
+{
+ return PyErr_SetExcFromWindowsErrWithFilename(exc, ierr, NULL);
+}
+
+PyObject *PyErr_SetFromWindowsErr(int ierr)
+{
+ return PyErr_SetExcFromWindowsErrWithFilename(PyExc_OSError,
+ ierr, NULL);
+}
+
+PyObject *PyErr_SetFromWindowsErrWithFilename(
+ int ierr,
+ const char *filename)
+{
+ PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
+ PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects(
+ PyExc_OSError,
+ ierr, name, NULL);
+ Py_XDECREF(name);
+ return result;
+}
+
+PyObject *PyErr_SetFromWindowsErrWithUnicodeFilename(
+ int ierr,
+ const Py_UNICODE *filename)
+{
+ PyObject *name = filename ? PyUnicode_FromWideChar(filename, -1) : NULL;
+ PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects(
+ PyExc_OSError,
+ ierr, name, NULL);
+ Py_XDECREF(name);
+ return result;
+}
+#endif /* MS_WINDOWS */
+
+PyObject *
+PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg,
+ PyObject *name, PyObject *path)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ int issubclass;
+ PyObject *kwargs, *error;
+
+ issubclass = PyObject_IsSubclass(exception, PyExc_ImportError);
+ if (issubclass < 0) {
+ return NULL;
+ }
+ else if (!issubclass) {
+ _PyErr_SetString(tstate, PyExc_TypeError,
+ "expected a subclass of ImportError");
+ return NULL;
+ }
+
+ if (msg == NULL) {
+ _PyErr_SetString(tstate, PyExc_TypeError,
+ "expected a message argument");
+ return NULL;
+ }
+
+ if (name == NULL) {
+ name = Py_None;
+ }
+ if (path == NULL) {
+ path = Py_None;
+ }
+
+ kwargs = PyDict_New();
+ if (kwargs == NULL) {
+ return NULL;
+ }
+ if (PyDict_SetItemString(kwargs, "name", name) < 0) {
+ goto done;
+ }
+ if (PyDict_SetItemString(kwargs, "path", path) < 0) {
+ goto done;
+ }
+
+ error = PyObject_VectorcallDict(exception, &msg, 1, kwargs);
+ if (error != NULL) {
+ _PyErr_SetObject(tstate, (PyObject *)Py_TYPE(error), error);
+ Py_DECREF(error);
+ }
+
+done:
+ Py_DECREF(kwargs);
+ return NULL;
+}
+
+PyObject *
+PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path)
+{
+ return PyErr_SetImportErrorSubclass(PyExc_ImportError, msg, name, path);
+}
+
+void
+_PyErr_BadInternalCall(const char *filename, int lineno)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ _PyErr_Format(tstate, PyExc_SystemError,
+ "%s:%d: bad argument to internal function",
+ filename, lineno);
+}
+
+/* Remove the preprocessor macro for PyErr_BadInternalCall() so that we can
+ export the entry point for existing object code: */
+#undef PyErr_BadInternalCall
+void
+PyErr_BadInternalCall(void)
+{
+ assert(0 && "bad argument to internal function");
+ PyThreadState *tstate = _PyThreadState_GET();
+ _PyErr_SetString(tstate, PyExc_SystemError,
+ "bad argument to internal function");
+}
+#define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__)
+
+
+static PyObject *
+_PyErr_FormatV(PyThreadState *tstate, PyObject *exception,
+ const char *format, va_list vargs)
+{
+ PyObject* string;
+
+ /* Issue #23571: PyUnicode_FromFormatV() must not be called with an
+ exception set, it calls arbitrary Python code like PyObject_Repr() */
+ _PyErr_Clear(tstate);
+
+ string = PyUnicode_FromFormatV(format, vargs);
+
+ _PyErr_SetObject(tstate, exception, string);
+ Py_XDECREF(string);
+ return NULL;
+}
+
+
+PyObject *
+PyErr_FormatV(PyObject *exception, const char *format, va_list vargs)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ return _PyErr_FormatV(tstate, exception, format, vargs);
+}
+
+
+PyObject *
+_PyErr_Format(PyThreadState *tstate, PyObject *exception,
+ const char *format, ...)
+{
+ va_list vargs;
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, format);
+#else
+ va_start(vargs);
+#endif
+ _PyErr_FormatV(tstate, exception, format, vargs);
+ va_end(vargs);
+ return NULL;
+}
+
+
+PyObject *
+PyErr_Format(PyObject *exception, const char *format, ...)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ va_list vargs;
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, format);
+#else
+ va_start(vargs);
+#endif
+ _PyErr_FormatV(tstate, exception, format, vargs);
+ va_end(vargs);
+ return NULL;
+}
+
+
+PyObject *
+PyErr_NewException(const char *name, PyObject *base, PyObject *dict)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyObject *modulename = NULL;
+ PyObject *classname = NULL;
+ PyObject *mydict = NULL;
+ PyObject *bases = NULL;
+ PyObject *result = NULL;
+
+ const char *dot = strrchr(name, '.');
+ if (dot == NULL) {
+ _PyErr_SetString(tstate, PyExc_SystemError,
+ "PyErr_NewException: name must be module.class");
+ return NULL;
+ }
+ if (base == NULL) {
+ base = PyExc_Exception;
+ }
+ if (dict == NULL) {
+ dict = mydict = PyDict_New();
+ if (dict == NULL)
+ goto failure;
+ }
+
+ if (_PyDict_GetItemIdWithError(dict, &PyId___module__) == NULL) {
+ if (_PyErr_Occurred(tstate)) {
+ goto failure;
+ }
+ modulename = PyUnicode_FromStringAndSize(name,
+ (Py_ssize_t)(dot-name));
+ if (modulename == NULL)
+ goto failure;
+ if (_PyDict_SetItemId(dict, &PyId___module__, modulename) != 0)
+ goto failure;
+ }
+ if (PyTuple_Check(base)) {
+ bases = base;
+ /* INCREF as we create a new ref in the else branch */
+ Py_INCREF(bases);
+ } else {
+ bases = PyTuple_Pack(1, base);
+ if (bases == NULL)
+ goto failure;
+ }
+ /* Create a real class. */
+ result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO",
+ dot+1, bases, dict);
+ failure:
+ Py_XDECREF(bases);
+ Py_XDECREF(mydict);
+ Py_XDECREF(classname);
+ Py_XDECREF(modulename);
+ return result;
+}
+
+
+/* Create an exception with docstring */
+PyObject *
+PyErr_NewExceptionWithDoc(const char *name, const char *doc,
+ PyObject *base, PyObject *dict)
+{
+ int result;
+ PyObject *ret = NULL;
+ PyObject *mydict = NULL; /* points to the dict only if we create it */
+ PyObject *docobj;
+
+ if (dict == NULL) {
+ dict = mydict = PyDict_New();
+ if (dict == NULL) {
+ return NULL;
+ }
+ }
+
+ if (doc != NULL) {
+ docobj = PyUnicode_FromString(doc);
+ if (docobj == NULL)
+ goto failure;
+ result = PyDict_SetItemString(dict, "__doc__", docobj);
+ Py_DECREF(docobj);
+ if (result < 0)
+ goto failure;
+ }
+
+ ret = PyErr_NewException(name, base, dict);
+ failure:
+ Py_XDECREF(mydict);
+ return ret;
+}
+
+
+PyDoc_STRVAR(UnraisableHookArgs__doc__,
+"UnraisableHookArgs\n\
+\n\
+Type used to pass arguments to sys.unraisablehook.");
+
+static PyTypeObject UnraisableHookArgsType;
+
+static PyStructSequence_Field UnraisableHookArgs_fields[] = {
+ {"exc_type", "Exception type"},
+ {"exc_value", "Exception value"},
+ {"exc_traceback", "Exception traceback"},
+ {"err_msg", "Error message"},
+ {"object", "Object causing the exception"},
+ {0}
+};
+
+static PyStructSequence_Desc UnraisableHookArgs_desc = {
+ .name = "UnraisableHookArgs",
+ .doc = UnraisableHookArgs__doc__,
+ .fields = UnraisableHookArgs_fields,
+ .n_in_sequence = 5
+};
+
+
+PyStatus
+_PyErr_Init(void)
+{
+ if (UnraisableHookArgsType.tp_name == NULL) {
+ if (PyStructSequence_InitType2(&UnraisableHookArgsType,
+ &UnraisableHookArgs_desc) < 0) {
+ return _PyStatus_ERR("failed to initialize UnraisableHookArgs type");
+ }
+ }
+ return _PyStatus_OK();
+}
+
+
+static PyObject *
+make_unraisable_hook_args(PyThreadState *tstate, PyObject *exc_type,
+ PyObject *exc_value, PyObject *exc_tb,
+ PyObject *err_msg, PyObject *obj)
+{
+ PyObject *args = PyStructSequence_New(&UnraisableHookArgsType);
+ if (args == NULL) {
+ return NULL;
+ }
+
+ Py_ssize_t pos = 0;
+#define ADD_ITEM(exc_type) \
+ do { \
+ if (exc_type == NULL) { \
+ exc_type = Py_None; \
+ } \
+ Py_INCREF(exc_type); \
+ PyStructSequence_SET_ITEM(args, pos++, exc_type); \
+ } while (0)
+
+
+ ADD_ITEM(exc_type);
+ ADD_ITEM(exc_value);
+ ADD_ITEM(exc_tb);
+ ADD_ITEM(err_msg);
+ ADD_ITEM(obj);
+#undef ADD_ITEM
+
+ if (_PyErr_Occurred(tstate)) {
+ Py_DECREF(args);
+ return NULL;
+ }
+ return args;
+}
+
+
+
+/* Default implementation of sys.unraisablehook.
+
+ It can be called to log the exception of a custom sys.unraisablehook.
+
+ Do nothing if sys.stderr attribute doesn't exist or is set to None. */
+static int
+write_unraisable_exc_file(PyThreadState *tstate, PyObject *exc_type,
+ PyObject *exc_value, PyObject *exc_tb,
+ PyObject *err_msg, PyObject *obj, PyObject *file)
+{
+ if (obj != NULL && obj != Py_None) {
+ if (err_msg != NULL && err_msg != Py_None) {
+ if (PyFile_WriteObject(err_msg, file, Py_PRINT_RAW) < 0) {
+ return -1;
+ }
+ if (PyFile_WriteString(": ", file) < 0) {
+ return -1;
+ }
+ }
+ else {
+ if (PyFile_WriteString("Exception ignored in: ", file) < 0) {
+ return -1;
+ }
+ }
+
+ if (PyFile_WriteObject(obj, file, 0) < 0) {
+ _PyErr_Clear(tstate);
+ if (PyFile_WriteString("<object repr() failed>", file) < 0) {
+ return -1;
+ }
+ }
+ if (PyFile_WriteString("\n", file) < 0) {
+ return -1;
+ }
+ }
+ else if (err_msg != NULL && err_msg != Py_None) {
+ if (PyFile_WriteObject(err_msg, file, Py_PRINT_RAW) < 0) {
+ return -1;
+ }
+ if (PyFile_WriteString(":\n", file) < 0) {
+ return -1;
+ }
+ }
+
+ if (exc_tb != NULL && exc_tb != Py_None) {
+ if (PyTraceBack_Print(exc_tb, file) < 0) {
+ /* continue even if writing the traceback failed */
+ _PyErr_Clear(tstate);
+ }
+ }
+
+ if (exc_type == NULL || exc_type == Py_None) {
+ return -1;
+ }
+
+ assert(PyExceptionClass_Check(exc_type));
+
+ PyObject *modulename = _PyObject_GetAttrId(exc_type, &PyId___module__);
+ if (modulename == NULL || !PyUnicode_Check(modulename)) {
+ Py_XDECREF(modulename);
+ _PyErr_Clear(tstate);
+ if (PyFile_WriteString("<unknown>", file) < 0) {
+ return -1;
+ }
+ }
+ else {
+ if (!_PyUnicode_EqualToASCIIId(modulename, &PyId_builtins)) {
+ if (PyFile_WriteObject(modulename, file, Py_PRINT_RAW) < 0) {
+ Py_DECREF(modulename);
+ return -1;
+ }
+ Py_DECREF(modulename);
+ if (PyFile_WriteString(".", file) < 0) {
+ return -1;
+ }
+ }
+ else {
+ Py_DECREF(modulename);
+ }
+ }
+
+ PyObject *qualname = _PyType_GetQualName((PyTypeObject *)exc_type);
+ if (qualname == NULL || !PyUnicode_Check(qualname)) {
+ Py_XDECREF(qualname);
+ _PyErr_Clear(tstate);
+ if (PyFile_WriteString("<unknown>", file) < 0) {
+ return -1;
+ }
+ }
+ else {
+ if (PyFile_WriteObject(qualname, file, Py_PRINT_RAW) < 0) {
+ Py_DECREF(qualname);
+ return -1;
+ }
+ Py_DECREF(qualname);
+ }
+
+ if (exc_value && exc_value != Py_None) {
+ if (PyFile_WriteString(": ", file) < 0) {
+ return -1;
+ }
+ if (PyFile_WriteObject(exc_value, file, Py_PRINT_RAW) < 0) {
+ _PyErr_Clear(tstate);
+ if (PyFile_WriteString("<exception str() failed>", file) < 0) {
+ return -1;
+ }
+ }
+ }
+
+ if (PyFile_WriteString("\n", file) < 0) {
+ return -1;
+ }
+
+ /* Explicitly call file.flush() */
+ PyObject *res = _PyObject_CallMethodIdNoArgs(file, &PyId_flush);
+ if (!res) {
+ return -1;
+ }
+ Py_DECREF(res);
+
+ return 0;
+}
+
+
+static int
+write_unraisable_exc(PyThreadState *tstate, PyObject *exc_type,
+ PyObject *exc_value, PyObject *exc_tb, PyObject *err_msg,
+ PyObject *obj)
+{
+ PyObject *file = _PySys_GetObjectId(&PyId_stderr);
+ if (file == NULL || file == Py_None) {
+ return 0;
+ }
+
+ /* Hold a strong reference to ensure that sys.stderr doesn't go away
+ while we use it */
+ Py_INCREF(file);
+ int res = write_unraisable_exc_file(tstate, exc_type, exc_value, exc_tb,
+ err_msg, obj, file);
+ Py_DECREF(file);
+
+ return res;
+}
+
+
+PyObject*
+_PyErr_WriteUnraisableDefaultHook(PyObject *args)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+
+ if (!Py_IS_TYPE(args, &UnraisableHookArgsType)) {
+ _PyErr_SetString(tstate, PyExc_TypeError,
+ "sys.unraisablehook argument type "
+ "must be UnraisableHookArgs");
+ return NULL;
+ }
+
+ /* Borrowed references */
+ PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0);
+ PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1);
+ PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2);
+ PyObject *err_msg = PyStructSequence_GET_ITEM(args, 3);
+ PyObject *obj = PyStructSequence_GET_ITEM(args, 4);
+
+ if (write_unraisable_exc(tstate, exc_type, exc_value, exc_tb, err_msg, obj) < 0) {
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+
+/* Call sys.unraisablehook().
+
+ This function can be used when an exception has occurred but there is no way
+ for Python to handle it. For example, when a destructor raises an exception
+ or during garbage collection (gc.collect()).
+
+ If err_msg_str is non-NULL, the error message is formatted as:
+ "Exception ignored %s" % err_msg_str. Otherwise, use "Exception ignored in"
+ error message.
+
+ An exception must be set when calling this function. */
+void
+_PyErr_WriteUnraisableMsg(const char *err_msg_str, PyObject *obj)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ _Py_EnsureTstateNotNULL(tstate);
+
+ PyObject *err_msg = NULL;
+ PyObject *exc_type, *exc_value, *exc_tb;
+ _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
+
+ assert(exc_type != NULL);
+
+ if (exc_type == NULL) {
+ /* sys.unraisablehook requires that at least exc_type is set */
+ goto default_hook;
+ }
+
+ if (exc_tb == NULL) {
+ PyFrameObject *frame = tstate->frame;
+ if (frame != NULL) {
+ exc_tb = _PyTraceBack_FromFrame(NULL, frame);
+ if (exc_tb == NULL) {
+ _PyErr_Clear(tstate);
+ }
+ }
+ }
+
+ _PyErr_NormalizeException(tstate, &exc_type, &exc_value, &exc_tb);
+
+ if (exc_tb != NULL && exc_tb != Py_None && PyTraceBack_Check(exc_tb)) {
+ if (PyException_SetTraceback(exc_value, exc_tb) < 0) {
+ _PyErr_Clear(tstate);
+ }
+ }
+
+ if (err_msg_str != NULL) {
+ err_msg = PyUnicode_FromFormat("Exception ignored %s", err_msg_str);
+ if (err_msg == NULL) {
+ PyErr_Clear();
+ }
+ }
+
+ PyObject *hook_args = make_unraisable_hook_args(
+ tstate, exc_type, exc_value, exc_tb, err_msg, obj);
+ if (hook_args == NULL) {
+ err_msg_str = ("Exception ignored on building "
+ "sys.unraisablehook arguments");
+ goto error;
+ }
+
+ _Py_IDENTIFIER(unraisablehook);
+ PyObject *hook = _PySys_GetObjectId(&PyId_unraisablehook);
+ if (hook == NULL) {
+ Py_DECREF(hook_args);
+ goto default_hook;
+ }
+
+ if (_PySys_Audit(tstate, "sys.unraisablehook", "OO", hook, hook_args) < 0) {
+ Py_DECREF(hook_args);
+ err_msg_str = "Exception ignored in audit hook";
+ obj = NULL;
+ goto error;
+ }
+
+ if (hook == Py_None) {
+ Py_DECREF(hook_args);
+ goto default_hook;
+ }
+
+ PyObject *res = PyObject_CallOneArg(hook, hook_args);
+ Py_DECREF(hook_args);
+ if (res != NULL) {
+ Py_DECREF(res);
+ goto done;
+ }
+
+ /* sys.unraisablehook failed: log its error using default hook */
+ obj = hook;
+ err_msg_str = NULL;
+
+error:
+ /* err_msg_str and obj have been updated and we have a new exception */
+ Py_XSETREF(err_msg, PyUnicode_FromString(err_msg_str ?
+ err_msg_str : "Exception ignored in sys.unraisablehook"));
+ Py_XDECREF(exc_type);
+ Py_XDECREF(exc_value);
+ Py_XDECREF(exc_tb);
+ _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
+
+default_hook:
+ /* Call the default unraisable hook (ignore failure) */
+ (void)write_unraisable_exc(tstate, exc_type, exc_value, exc_tb,
+ err_msg, obj);
+
+done:
+ Py_XDECREF(exc_type);
+ Py_XDECREF(exc_value);
+ Py_XDECREF(exc_tb);
+ Py_XDECREF(err_msg);
+ _PyErr_Clear(tstate); /* Just in case */
+}
+
+
+void
+PyErr_WriteUnraisable(PyObject *obj)
+{
+ _PyErr_WriteUnraisableMsg(NULL, obj);
+}
+
+
+extern PyObject *PyModule_GetWarningsModule(void);
+
+
+void
+PyErr_SyntaxLocation(const char *filename, int lineno)
+{
+ PyErr_SyntaxLocationEx(filename, lineno, -1);
+}
+
+
+/* Set file and line information for the current exception.
+ If the exception is not a SyntaxError, also sets additional attributes
+ to make printing of exceptions believe it is a syntax error. */
+
+void
+PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset)
+{
+ PyObject *exc, *v, *tb, *tmp;
+ _Py_IDENTIFIER(filename);
+ _Py_IDENTIFIER(lineno);
+ _Py_IDENTIFIER(msg);
+ _Py_IDENTIFIER(offset);
+ _Py_IDENTIFIER(print_file_and_line);
+ _Py_IDENTIFIER(text);
+ PyThreadState *tstate = _PyThreadState_GET();
+
+ /* add attributes for the line number and filename for the error */
+ _PyErr_Fetch(tstate, &exc, &v, &tb);
+ _PyErr_NormalizeException(tstate, &exc, &v, &tb);
+ /* XXX check that it is, indeed, a syntax error. It might not
+ * be, though. */
+ tmp = PyLong_FromLong(lineno);
+ if (tmp == NULL)
+ _PyErr_Clear(tstate);
+ else {
+ if (_PyObject_SetAttrId(v, &PyId_lineno, tmp)) {
+ _PyErr_Clear(tstate);
+ }
+ Py_DECREF(tmp);
+ }
+ tmp = NULL;
+ if (col_offset >= 0) {
+ tmp = PyLong_FromLong(col_offset);
+ if (tmp == NULL) {
+ _PyErr_Clear(tstate);
+ }
+ }
+ if (_PyObject_SetAttrId(v, &PyId_offset, tmp ? tmp : Py_None)) {
+ _PyErr_Clear(tstate);
+ }
+ Py_XDECREF(tmp);
+ if (filename != NULL) {
+ if (_PyObject_SetAttrId(v, &PyId_filename, filename)) {
+ _PyErr_Clear(tstate);
+ }
+
+ tmp = PyErr_ProgramTextObject(filename, lineno);
+ if (tmp) {
+ if (_PyObject_SetAttrId(v, &PyId_text, tmp)) {
+ _PyErr_Clear(tstate);
+ }
+ Py_DECREF(tmp);
+ }
+ }
+ if (exc != PyExc_SyntaxError) {
+ if (!_PyObject_HasAttrId(v, &PyId_msg)) {
+ tmp = PyObject_Str(v);
+ if (tmp) {
+ if (_PyObject_SetAttrId(v, &PyId_msg, tmp)) {
+ _PyErr_Clear(tstate);
+ }
+ Py_DECREF(tmp);
+ }
+ else {
+ _PyErr_Clear(tstate);
+ }
+ }
+ if (!_PyObject_HasAttrId(v, &PyId_print_file_and_line)) {
+ if (_PyObject_SetAttrId(v, &PyId_print_file_and_line,
+ Py_None)) {
+ _PyErr_Clear(tstate);
+ }
+ }
+ }
+ _PyErr_Restore(tstate, exc, v, tb);
+}
+
+void
+PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyObject *fileobj;
+ if (filename != NULL) {
+ fileobj = PyUnicode_DecodeFSDefault(filename);
+ if (fileobj == NULL) {
+ _PyErr_Clear(tstate);
+ }
+ }
+ else {
+ fileobj = NULL;
+ }
+ PyErr_SyntaxLocationObject(fileobj, lineno, col_offset);
+ Py_XDECREF(fileobj);
+}
+
+/* Attempt to load the line of text that the exception refers to. If it
+ fails, it will return NULL but will not set an exception.
+
+ XXX The functionality of this function is quite similar to the
+ functionality in tb_displayline() in traceback.c. */
+
+static PyObject *
+err_programtext(PyThreadState *tstate, FILE *fp, int lineno)
+{
+ int i;
+ char linebuf[1000];
+ if (fp == NULL) {
+ return NULL;
+ }
+
+ for (i = 0; i < lineno; i++) {
+ char *pLastChar = &linebuf[sizeof(linebuf) - 2];
+ do {
+ *pLastChar = '\0';
+ if (Py_UniversalNewlineFgets(linebuf, sizeof linebuf,
+ fp, NULL) == NULL) {
+ goto after_loop;
+ }
+ /* fgets read *something*; if it didn't get as
+ far as pLastChar, it must have found a newline
+ or hit the end of the file; if pLastChar is \n,
+ it obviously found a newline; else we haven't
+ yet seen a newline, so must continue */
+ } while (*pLastChar != '\0' && *pLastChar != '\n');
+ }
+
+after_loop:
+ fclose(fp);
+ if (i == lineno) {
+ PyObject *res;
+ res = PyUnicode_FromString(linebuf);
+ if (res == NULL)
+ _PyErr_Clear(tstate);
+ return res;
+ }
+ return NULL;
+}
+
+PyObject *
+PyErr_ProgramText(const char *filename, int lineno)
+{
+ FILE *fp;
+ if (filename == NULL || *filename == '\0' || lineno <= 0) {
+ return NULL;
+ }
+ PyThreadState *tstate = _PyThreadState_GET();
+ fp = _Py_fopen(filename, "r" PY_STDIOTEXTMODE);
+ return err_programtext(tstate, fp, lineno);
+}
+
+PyObject *
+PyErr_ProgramTextObject(PyObject *filename, int lineno)
+{
+ if (filename == NULL || lineno <= 0) {
+ return NULL;
+ }
+
+ PyThreadState *tstate = _PyThreadState_GET();
+ FILE *fp = _Py_fopen_obj(filename, "r" PY_STDIOTEXTMODE);
+ if (fp == NULL) {
+ _PyErr_Clear(tstate);
+ return NULL;
+ }
+ return err_programtext(tstate, fp, lineno);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/contrib/tools/python3/src/Python/fileutils.c b/contrib/tools/python3/src/Python/fileutils.c
new file mode 100644
index 00000000000..26e97df4ef3
--- /dev/null
+++ b/contrib/tools/python3/src/Python/fileutils.c
@@ -0,0 +1,2276 @@
+#include "Python.h"
+#include "pycore_fileutils.h"
+#include "osdefs.h" // SEP
+#include <locale.h>
+
+#ifdef MS_WINDOWS
+# include <malloc.h>
+# include <windows.h>
+extern int winerror_to_errno(int);
+#endif
+
+#ifdef HAVE_LANGINFO_H
+#include <langinfo.h>
+#endif
+
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION
+#include <iconv.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif /* HAVE_FCNTL_H */
+
+#ifdef O_CLOEXEC
+/* Does open() support the O_CLOEXEC flag? Possible values:
+
+ -1: unknown
+ 0: open() ignores O_CLOEXEC flag, ex: Linux kernel older than 2.6.23
+ 1: open() supports O_CLOEXEC flag, close-on-exec is set
+
+ The flag is used by _Py_open(), _Py_open_noraise(), io.FileIO
+ and os.open(). */
+int _Py_open_cloexec_works = -1;
+#endif
+
+// The value must be the same in unicodeobject.c.
+#define MAX_UNICODE 0x10ffff
+
+// mbstowcs() and mbrtowc() errors
+static const size_t DECODE_ERROR = ((size_t)-1);
+static const size_t INCOMPLETE_CHARACTER = (size_t)-2;
+
+
+static int
+get_surrogateescape(_Py_error_handler errors, int *surrogateescape)
+{
+ switch (errors)
+ {
+ case _Py_ERROR_STRICT:
+ *surrogateescape = 0;
+ return 0;
+ case _Py_ERROR_SURROGATEESCAPE:
+ *surrogateescape = 1;
+ return 0;
+ default:
+ return -1;
+ }
+}
+
+
+PyObject *
+_Py_device_encoding(int fd)
+{
+#if defined(MS_WINDOWS)
+ UINT cp;
+#endif
+ int valid;
+ Py_BEGIN_ALLOW_THREADS
+ _Py_BEGIN_SUPPRESS_IPH
+ valid = isatty(fd);
+ _Py_END_SUPPRESS_IPH
+ Py_END_ALLOW_THREADS
+ if (!valid)
+ Py_RETURN_NONE;
+
+#if defined(MS_WINDOWS)
+ if (fd == 0)
+ cp = GetConsoleCP();
+ else if (fd == 1 || fd == 2)
+ cp = GetConsoleOutputCP();
+ else
+ cp = 0;
+ /* GetConsoleCP() and GetConsoleOutputCP() return 0 if the application
+ has no console */
+ if (cp != 0)
+ return PyUnicode_FromFormat("cp%u", (unsigned int)cp);
+#elif defined(CODESET)
+ {
+ char *codeset = nl_langinfo(CODESET);
+ if (codeset != NULL && codeset[0] != 0)
+ return PyUnicode_FromString(codeset);
+ }
+#endif
+ Py_RETURN_NONE;
+}
+
+
+static size_t
+is_valid_wide_char(wchar_t ch)
+{
+#ifdef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION
+ /* Oracle Solaris doesn't use Unicode code points as wchar_t encoding
+ for non-Unicode locales, which makes values higher than MAX_UNICODE
+ possibly valid. */
+ return 1;
+#endif
+ if (Py_UNICODE_IS_SURROGATE(ch)) {
+ // Reject lone surrogate characters
+ return 0;
+ }
+ if (ch > MAX_UNICODE) {
+ // bpo-35883: Reject characters outside [U+0000; U+10ffff] range.
+ // The glibc mbstowcs() UTF-8 decoder does not respect the RFC 3629,
+ // it creates characters outside the [U+0000; U+10ffff] range:
+ // https://sourceware.org/bugzilla/show_bug.cgi?id=2373
+ return 0;
+ }
+ return 1;
+}
+
+
+static size_t
+_Py_mbstowcs(wchar_t *dest, const char *src, size_t n)
+{
+ size_t count = mbstowcs(dest, src, n);
+ if (dest != NULL && count != DECODE_ERROR) {
+ for (size_t i=0; i < count; i++) {
+ wchar_t ch = dest[i];
+ if (!is_valid_wide_char(ch)) {
+ return DECODE_ERROR;
+ }
+ }
+ }
+ return count;
+}
+
+
+#ifdef HAVE_MBRTOWC
+static size_t
+_Py_mbrtowc(wchar_t *pwc, const char *str, size_t len, mbstate_t *pmbs)
+{
+ assert(pwc != NULL);
+ size_t count = mbrtowc(pwc, str, len, pmbs);
+ if (count != 0 && count != DECODE_ERROR && count != INCOMPLETE_CHARACTER) {
+ if (!is_valid_wide_char(*pwc)) {
+ return DECODE_ERROR;
+ }
+ }
+ return count;
+}
+#endif
+
+
+#if !defined(_Py_FORCE_UTF8_FS_ENCODING) && !defined(MS_WINDOWS)
+
+#define USE_FORCE_ASCII
+
+extern int _Py_normalize_encoding(const char *, char *, size_t);
+
+/* Workaround FreeBSD and OpenIndiana locale encoding issue with the C locale
+ and POSIX locale. nl_langinfo(CODESET) announces an alias of the
+ ASCII encoding, whereas mbstowcs() and wcstombs() functions use the
+ ISO-8859-1 encoding. The problem is that os.fsencode() and os.fsdecode() use
+ locale.getpreferredencoding() codec. For example, if command line arguments
+ are decoded by mbstowcs() and encoded back by os.fsencode(), we get a
+ UnicodeEncodeError instead of retrieving the original byte string.
+
+ The workaround is enabled if setlocale(LC_CTYPE, NULL) returns "C",
+ nl_langinfo(CODESET) announces "ascii" (or an alias to ASCII), and at least
+ one byte in range 0x80-0xff can be decoded from the locale encoding. The
+ workaround is also enabled on error, for example if getting the locale
+ failed.
+
+ On HP-UX with the C locale or the POSIX locale, nl_langinfo(CODESET)
+ announces "roman8" but mbstowcs() uses Latin1 in practice. Force also the
+ ASCII encoding in this case.
+
+ Values of force_ascii:
+
+ 1: the workaround is used: Py_EncodeLocale() uses
+ encode_ascii_surrogateescape() and Py_DecodeLocale() uses
+ decode_ascii()
+ 0: the workaround is not used: Py_EncodeLocale() uses wcstombs() and
+ Py_DecodeLocale() uses mbstowcs()
+ -1: unknown, need to call check_force_ascii() to get the value
+*/
+static int force_ascii = -1;
+
+static int
+check_force_ascii(void)
+{
+ char *loc = setlocale(LC_CTYPE, NULL);
+ if (loc == NULL) {
+ goto error;
+ }
+ if (strcmp(loc, "C") != 0 && strcmp(loc, "POSIX") != 0) {
+ /* the LC_CTYPE locale is different than C and POSIX */
+ return 0;
+ }
+
+#if defined(HAVE_LANGINFO_H) && defined(CODESET)
+ const char *codeset = nl_langinfo(CODESET);
+ if (!codeset || codeset[0] == '\0') {
+ /* CODESET is not set or empty */
+ goto error;
+ }
+
+ char encoding[20]; /* longest name: "iso_646.irv_1991\0" */
+ if (!_Py_normalize_encoding(codeset, encoding, sizeof(encoding))) {
+ goto error;
+ }
+
+#ifdef __hpux
+ if (strcmp(encoding, "roman8") == 0) {
+ unsigned char ch;
+ wchar_t wch;
+ size_t res;
+
+ ch = (unsigned char)0xA7;
+ res = _Py_mbstowcs(&wch, (char*)&ch, 1);
+ if (res != DECODE_ERROR && wch == L'\xA7') {
+ /* On HP-UX with C locale or the POSIX locale,
+ nl_langinfo(CODESET) announces "roman8", whereas mbstowcs() uses
+ Latin1 encoding in practice. Force ASCII in this case.
+
+ Roman8 decodes 0xA7 to U+00CF. Latin1 decodes 0xA7 to U+00A7. */
+ return 1;
+ }
+ }
+#else
+ const char* ascii_aliases[] = {
+ "ascii",
+ /* Aliases from Lib/encodings/aliases.py */
+ "646",
+ "ansi_x3.4_1968",
+ "ansi_x3.4_1986",
+ "ansi_x3_4_1968",
+ "cp367",
+ "csascii",
+ "ibm367",
+ "iso646_us",
+ "iso_646.irv_1991",
+ "iso_ir_6",
+ "us",
+ "us_ascii",
+ NULL
+ };
+
+ int is_ascii = 0;
+ for (const char **alias=ascii_aliases; *alias != NULL; alias++) {
+ if (strcmp(encoding, *alias) == 0) {
+ is_ascii = 1;
+ break;
+ }
+ }
+ if (!is_ascii) {
+ /* nl_langinfo(CODESET) is not "ascii" or an alias of ASCII */
+ return 0;
+ }
+
+ for (unsigned int i=0x80; i<=0xff; i++) {
+ char ch[1];
+ wchar_t wch[1];
+ size_t res;
+
+ unsigned uch = (unsigned char)i;
+ ch[0] = (char)uch;
+ res = _Py_mbstowcs(wch, ch, 1);
+ if (res != DECODE_ERROR) {
+ /* decoding a non-ASCII character from the locale encoding succeed:
+ the locale encoding is not ASCII, force ASCII */
+ return 1;
+ }
+ }
+ /* None of the bytes in the range 0x80-0xff can be decoded from the locale
+ encoding: the locale encoding is really ASCII */
+#endif /* !defined(__hpux) */
+ return 0;
+#else
+ /* nl_langinfo(CODESET) is not available: always force ASCII */
+ return 1;
+#endif /* defined(HAVE_LANGINFO_H) && defined(CODESET) */
+
+error:
+ /* if an error occurred, force the ASCII encoding */
+ return 1;
+}
+
+
+int
+_Py_GetForceASCII(void)
+{
+ if (force_ascii == -1) {
+ force_ascii = check_force_ascii();
+ }
+ return force_ascii;
+}
+
+
+void
+_Py_ResetForceASCII(void)
+{
+ force_ascii = -1;
+}
+
+
+static int
+encode_ascii(const wchar_t *text, char **str,
+ size_t *error_pos, const char **reason,
+ int raw_malloc, _Py_error_handler errors)
+{
+ char *result = NULL, *out;
+ size_t len, i;
+ wchar_t ch;
+
+ int surrogateescape;
+ if (get_surrogateescape(errors, &surrogateescape) < 0) {
+ return -3;
+ }
+
+ len = wcslen(text);
+
+ /* +1 for NULL byte */
+ if (raw_malloc) {
+ result = PyMem_RawMalloc(len + 1);
+ }
+ else {
+ result = PyMem_Malloc(len + 1);
+ }
+ if (result == NULL) {
+ return -1;
+ }
+
+ out = result;
+ for (i=0; i<len; i++) {
+ ch = text[i];
+
+ if (ch <= 0x7f) {
+ /* ASCII character */
+ *out++ = (char)ch;
+ }
+ else if (surrogateescape && 0xdc80 <= ch && ch <= 0xdcff) {
+ /* UTF-8b surrogate */
+ *out++ = (char)(ch - 0xdc00);
+ }
+ else {
+ if (raw_malloc) {
+ PyMem_RawFree(result);
+ }
+ else {
+ PyMem_Free(result);
+ }
+ if (error_pos != NULL) {
+ *error_pos = i;
+ }
+ if (reason) {
+ *reason = "encoding error";
+ }
+ return -2;
+ }
+ }
+ *out = '\0';
+ *str = result;
+ return 0;
+}
+#else
+int
+_Py_GetForceASCII(void)
+{
+ return 0;
+}
+
+void
+_Py_ResetForceASCII(void)
+{
+ /* nothing to do */
+}
+#endif /* !defined(_Py_FORCE_UTF8_FS_ENCODING) && !defined(MS_WINDOWS) */
+
+
+#if !defined(HAVE_MBRTOWC) || defined(USE_FORCE_ASCII)
+static int
+decode_ascii(const char *arg, wchar_t **wstr, size_t *wlen,
+ const char **reason, _Py_error_handler errors)
+{
+ wchar_t *res;
+ unsigned char *in;
+ wchar_t *out;
+ size_t argsize = strlen(arg) + 1;
+
+ int surrogateescape;
+ if (get_surrogateescape(errors, &surrogateescape) < 0) {
+ return -3;
+ }
+
+ if (argsize > PY_SSIZE_T_MAX / sizeof(wchar_t)) {
+ return -1;
+ }
+ res = PyMem_RawMalloc(argsize * sizeof(wchar_t));
+ if (!res) {
+ return -1;
+ }
+
+ out = res;
+ for (in = (unsigned char*)arg; *in; in++) {
+ unsigned char ch = *in;
+ if (ch < 128) {
+ *out++ = ch;
+ }
+ else {
+ if (!surrogateescape) {
+ PyMem_RawFree(res);
+ if (wlen) {
+ *wlen = in - (unsigned char*)arg;
+ }
+ if (reason) {
+ *reason = "decoding error";
+ }
+ return -2;
+ }
+ *out++ = 0xdc00 + ch;
+ }
+ }
+ *out = 0;
+
+ if (wlen != NULL) {
+ *wlen = out - res;
+ }
+ *wstr = res;
+ return 0;
+}
+#endif /* !HAVE_MBRTOWC */
+
+static int
+decode_current_locale(const char* arg, wchar_t **wstr, size_t *wlen,
+ const char **reason, _Py_error_handler errors)
+{
+ wchar_t *res;
+ size_t argsize;
+ size_t count;
+#ifdef HAVE_MBRTOWC
+ unsigned char *in;
+ wchar_t *out;
+ mbstate_t mbs;
+#endif
+
+ int surrogateescape;
+ if (get_surrogateescape(errors, &surrogateescape) < 0) {
+ return -3;
+ }
+
+#ifdef HAVE_BROKEN_MBSTOWCS
+ /* Some platforms have a broken implementation of
+ * mbstowcs which does not count the characters that
+ * would result from conversion. Use an upper bound.
+ */
+ argsize = strlen(arg);
+#else
+ argsize = _Py_mbstowcs(NULL, arg, 0);
+#endif
+ if (argsize != DECODE_ERROR) {
+ if (argsize > PY_SSIZE_T_MAX / sizeof(wchar_t) - 1) {
+ return -1;
+ }
+ res = (wchar_t *)PyMem_RawMalloc((argsize + 1) * sizeof(wchar_t));
+ if (!res) {
+ return -1;
+ }
+
+ count = _Py_mbstowcs(res, arg, argsize + 1);
+ if (count != DECODE_ERROR) {
+ *wstr = res;
+ if (wlen != NULL) {
+ *wlen = count;
+ }
+ return 0;
+ }
+ PyMem_RawFree(res);
+ }
+
+ /* Conversion failed. Fall back to escaping with surrogateescape. */
+#ifdef HAVE_MBRTOWC
+ /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */
+
+ /* Overallocate; as multi-byte characters are in the argument, the
+ actual output could use less memory. */
+ argsize = strlen(arg) + 1;
+ if (argsize > PY_SSIZE_T_MAX / sizeof(wchar_t)) {
+ return -1;
+ }
+ res = (wchar_t*)PyMem_RawMalloc(argsize * sizeof(wchar_t));
+ if (!res) {
+ return -1;
+ }
+
+ in = (unsigned char*)arg;
+ out = res;
+ memset(&mbs, 0, sizeof mbs);
+ while (argsize) {
+ size_t converted = _Py_mbrtowc(out, (char*)in, argsize, &mbs);
+ if (converted == 0) {
+ /* Reached end of string; null char stored. */
+ break;
+ }
+
+ if (converted == INCOMPLETE_CHARACTER) {
+ /* Incomplete character. This should never happen,
+ since we provide everything that we have -
+ unless there is a bug in the C library, or I
+ misunderstood how mbrtowc works. */
+ goto decode_error;
+ }
+
+ if (converted == DECODE_ERROR) {
+ if (!surrogateescape) {
+ goto decode_error;
+ }
+
+ /* Decoding error. Escape as UTF-8b, and start over in the initial
+ shift state. */
+ *out++ = 0xdc00 + *in++;
+ argsize--;
+ memset(&mbs, 0, sizeof mbs);
+ continue;
+ }
+
+ // _Py_mbrtowc() reject lone surrogate characters
+ assert(!Py_UNICODE_IS_SURROGATE(*out));
+
+ /* successfully converted some bytes */
+ in += converted;
+ argsize -= converted;
+ out++;
+ }
+ if (wlen != NULL) {
+ *wlen = out - res;
+ }
+ *wstr = res;
+ return 0;
+
+decode_error:
+ PyMem_RawFree(res);
+ if (wlen) {
+ *wlen = in - (unsigned char*)arg;
+ }
+ if (reason) {
+ *reason = "decoding error";
+ }
+ return -2;
+#else /* HAVE_MBRTOWC */
+ /* Cannot use C locale for escaping; manually escape as if charset
+ is ASCII (i.e. escape all bytes > 128. This will still roundtrip
+ correctly in the locale's charset, which must be an ASCII superset. */
+ return decode_ascii(arg, wstr, wlen, reason, errors);
+#endif /* HAVE_MBRTOWC */
+}
+
+
+/* Decode a byte string from the locale encoding.
+
+ Use the strict error handler if 'surrogateescape' is zero. Use the
+ surrogateescape error handler if 'surrogateescape' is non-zero: undecodable
+ bytes are decoded as characters in range U+DC80..U+DCFF. If a byte sequence
+ can be decoded as a surrogate character, escape the bytes using the
+ surrogateescape error handler instead of decoding them.
+
+ On success, return 0 and write the newly allocated wide character string into
+ *wstr (use PyMem_RawFree() to free the memory). If wlen is not NULL, write
+ the number of wide characters excluding the null character into *wlen.
+
+ On memory allocation failure, return -1.
+
+ On decoding error, return -2. If wlen is not NULL, write the start of
+ invalid byte sequence in the input string into *wlen. If reason is not NULL,
+ write the decoding error message into *reason.
+
+ Return -3 if the error handler 'errors' is not supported.
+
+ Use the Py_EncodeLocaleEx() function to encode the character string back to
+ a byte string. */
+int
+_Py_DecodeLocaleEx(const char* arg, wchar_t **wstr, size_t *wlen,
+ const char **reason,
+ int current_locale, _Py_error_handler errors)
+{
+ if (current_locale) {
+#ifdef _Py_FORCE_UTF8_LOCALE
+ return _Py_DecodeUTF8Ex(arg, strlen(arg), wstr, wlen, reason,
+ errors);
+#else
+ return decode_current_locale(arg, wstr, wlen, reason, errors);
+#endif
+ }
+
+#ifdef _Py_FORCE_UTF8_FS_ENCODING
+ return _Py_DecodeUTF8Ex(arg, strlen(arg), wstr, wlen, reason,
+ errors);
+#else
+ int use_utf8 = (Py_UTF8Mode == 1);
+#ifdef MS_WINDOWS
+ use_utf8 |= !Py_LegacyWindowsFSEncodingFlag;
+#endif
+ if (use_utf8) {
+ return _Py_DecodeUTF8Ex(arg, strlen(arg), wstr, wlen, reason,
+ errors);
+ }
+
+#ifdef USE_FORCE_ASCII
+ if (force_ascii == -1) {
+ force_ascii = check_force_ascii();
+ }
+
+ if (force_ascii) {
+ /* force ASCII encoding to workaround mbstowcs() issue */
+ return decode_ascii(arg, wstr, wlen, reason, errors);
+ }
+#endif
+
+ return decode_current_locale(arg, wstr, wlen, reason, errors);
+#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
+}
+
+
+/* Decode a byte string from the locale encoding with the
+ surrogateescape error handler: undecodable bytes are decoded as characters
+ in range U+DC80..U+DCFF. If a byte sequence can be decoded as a surrogate
+ character, escape the bytes using the surrogateescape error handler instead
+ of decoding them.
+
+ Return a pointer to a newly allocated wide character string, use
+ PyMem_RawFree() to free the memory. If size is not NULL, write the number of
+ wide characters excluding the null character into *size
+
+ Return NULL on decoding error or memory allocation error. If *size* is not
+ NULL, *size is set to (size_t)-1 on memory error or set to (size_t)-2 on
+ decoding error.
+
+ Decoding errors should never happen, unless there is a bug in the C
+ library.
+
+ Use the Py_EncodeLocale() function to encode the character string back to a
+ byte string. */
+wchar_t*
+Py_DecodeLocale(const char* arg, size_t *wlen)
+{
+ wchar_t *wstr;
+ int res = _Py_DecodeLocaleEx(arg, &wstr, wlen,
+ NULL, 0,
+ _Py_ERROR_SURROGATEESCAPE);
+ if (res != 0) {
+ assert(res != -3);
+ if (wlen != NULL) {
+ *wlen = (size_t)res;
+ }
+ return NULL;
+ }
+ return wstr;
+}
+
+
+static int
+encode_current_locale(const wchar_t *text, char **str,
+ size_t *error_pos, const char **reason,
+ int raw_malloc, _Py_error_handler errors)
+{
+ const size_t len = wcslen(text);
+ char *result = NULL, *bytes = NULL;
+ size_t i, size, converted;
+ wchar_t c, buf[2];
+
+ int surrogateescape;
+ if (get_surrogateescape(errors, &surrogateescape) < 0) {
+ return -3;
+ }
+
+ /* The function works in two steps:
+ 1. compute the length of the output buffer in bytes (size)
+ 2. outputs the bytes */
+ size = 0;
+ buf[1] = 0;
+ while (1) {
+ for (i=0; i < len; i++) {
+ c = text[i];
+ if (c >= 0xdc80 && c <= 0xdcff) {
+ if (!surrogateescape) {
+ goto encode_error;
+ }
+ /* UTF-8b surrogate */
+ if (bytes != NULL) {
+ *bytes++ = c - 0xdc00;
+ size--;
+ }
+ else {
+ size++;
+ }
+ continue;
+ }
+ else {
+ buf[0] = c;
+ if (bytes != NULL) {
+ converted = wcstombs(bytes, buf, size);
+ }
+ else {
+ converted = wcstombs(NULL, buf, 0);
+ }
+ if (converted == DECODE_ERROR) {
+ goto encode_error;
+ }
+ if (bytes != NULL) {
+ bytes += converted;
+ size -= converted;
+ }
+ else {
+ size += converted;
+ }
+ }
+ }
+ if (result != NULL) {
+ *bytes = '\0';
+ break;
+ }
+
+ size += 1; /* nul byte at the end */
+ if (raw_malloc) {
+ result = PyMem_RawMalloc(size);
+ }
+ else {
+ result = PyMem_Malloc(size);
+ }
+ if (result == NULL) {
+ return -1;
+ }
+ bytes = result;
+ }
+ *str = result;
+ return 0;
+
+encode_error:
+ if (raw_malloc) {
+ PyMem_RawFree(result);
+ }
+ else {
+ PyMem_Free(result);
+ }
+ if (error_pos != NULL) {
+ *error_pos = i;
+ }
+ if (reason) {
+ *reason = "encoding error";
+ }
+ return -2;
+}
+
+
+/* Encode a string to the locale encoding.
+
+ Parameters:
+
+ * raw_malloc: if non-zero, allocate memory using PyMem_RawMalloc() instead
+ of PyMem_Malloc().
+ * current_locale: if non-zero, use the current LC_CTYPE, otherwise use
+ Python filesystem encoding.
+ * errors: error handler like "strict" or "surrogateescape".
+
+ Return value:
+
+ 0: success, *str is set to a newly allocated decoded string.
+ -1: memory allocation failure
+ -2: encoding error, set *error_pos and *reason (if set).
+ -3: the error handler 'errors' is not supported.
+ */
+static int
+encode_locale_ex(const wchar_t *text, char **str, size_t *error_pos,
+ const char **reason,
+ int raw_malloc, int current_locale, _Py_error_handler errors)
+{
+ if (current_locale) {
+#ifdef _Py_FORCE_UTF8_LOCALE
+ return _Py_EncodeUTF8Ex(text, str, error_pos, reason,
+ raw_malloc, errors);
+#else
+ return encode_current_locale(text, str, error_pos, reason,
+ raw_malloc, errors);
+#endif
+ }
+
+#ifdef _Py_FORCE_UTF8_FS_ENCODING
+ return _Py_EncodeUTF8Ex(text, str, error_pos, reason,
+ raw_malloc, errors);
+#else
+ int use_utf8 = (Py_UTF8Mode == 1);
+#ifdef MS_WINDOWS
+ use_utf8 |= !Py_LegacyWindowsFSEncodingFlag;
+#endif
+ if (use_utf8) {
+ return _Py_EncodeUTF8Ex(text, str, error_pos, reason,
+ raw_malloc, errors);
+ }
+
+#ifdef USE_FORCE_ASCII
+ if (force_ascii == -1) {
+ force_ascii = check_force_ascii();
+ }
+
+ if (force_ascii) {
+ return encode_ascii(text, str, error_pos, reason,
+ raw_malloc, errors);
+ }
+#endif
+
+ return encode_current_locale(text, str, error_pos, reason,
+ raw_malloc, errors);
+#endif /* _Py_FORCE_UTF8_FS_ENCODING */
+}
+
+static char*
+encode_locale(const wchar_t *text, size_t *error_pos,
+ int raw_malloc, int current_locale)
+{
+ char *str;
+ int res = encode_locale_ex(text, &str, error_pos, NULL,
+ raw_malloc, current_locale,
+ _Py_ERROR_SURROGATEESCAPE);
+ if (res != -2 && error_pos) {
+ *error_pos = (size_t)-1;
+ }
+ if (res != 0) {
+ return NULL;
+ }
+ return str;
+}
+
+/* Encode a wide character string to the locale encoding with the
+ surrogateescape error handler: surrogate characters in the range
+ U+DC80..U+DCFF are converted to bytes 0x80..0xFF.
+
+ Return a pointer to a newly allocated byte string, use PyMem_Free() to free
+ the memory. Return NULL on encoding or memory allocation error.
+
+ If error_pos is not NULL, *error_pos is set to (size_t)-1 on success, or set
+ to the index of the invalid character on encoding error.
+
+ Use the Py_DecodeLocale() function to decode the bytes string back to a wide
+ character string. */
+char*
+Py_EncodeLocale(const wchar_t *text, size_t *error_pos)
+{
+ return encode_locale(text, error_pos, 0, 0);
+}
+
+
+/* Similar to Py_EncodeLocale(), but result must be freed by PyMem_RawFree()
+ instead of PyMem_Free(). */
+char*
+_Py_EncodeLocaleRaw(const wchar_t *text, size_t *error_pos)
+{
+ return encode_locale(text, error_pos, 1, 0);
+}
+
+
+int
+_Py_EncodeLocaleEx(const wchar_t *text, char **str,
+ size_t *error_pos, const char **reason,
+ int current_locale, _Py_error_handler errors)
+{
+ return encode_locale_ex(text, str, error_pos, reason, 1,
+ current_locale, errors);
+}
+
+#ifdef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION
+
+/* Check whether current locale uses Unicode as internal wchar_t form. */
+int
+_Py_LocaleUsesNonUnicodeWchar(void)
+{
+ /* Oracle Solaris uses non-Unicode internal wchar_t form for
+ non-Unicode locales and hence needs conversion to UTF first. */
+ char* codeset = nl_langinfo(CODESET);
+ if (!codeset) {
+ return 0;
+ }
+ /* 646 refers to ISO/IEC 646 standard that corresponds to ASCII encoding */
+ return (strcmp(codeset, "UTF-8") != 0 && strcmp(codeset, "646") != 0);
+}
+
+static wchar_t *
+_Py_ConvertWCharForm(const wchar_t *source, Py_ssize_t size,
+ const char *tocode, const char *fromcode)
+{
+ Py_BUILD_ASSERT(sizeof(wchar_t) == 4);
+
+ /* Ensure we won't overflow the size. */
+ if (size > (PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(wchar_t))) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ /* the string doesn't have to be NULL terminated */
+ wchar_t* target = PyMem_Malloc(size * sizeof(wchar_t));
+ if (target == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ iconv_t cd = iconv_open(tocode, fromcode);
+ if (cd == (iconv_t)-1) {
+ PyErr_Format(PyExc_ValueError, "iconv_open() failed");
+ PyMem_Free(target);
+ return NULL;
+ }
+
+ char *inbuf = (char *) source;
+ char *outbuf = (char *) target;
+ size_t inbytesleft = sizeof(wchar_t) * size;
+ size_t outbytesleft = inbytesleft;
+
+ size_t ret = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
+ if (ret == DECODE_ERROR) {
+ PyErr_Format(PyExc_ValueError, "iconv() failed");
+ PyMem_Free(target);
+ iconv_close(cd);
+ return NULL;
+ }
+
+ iconv_close(cd);
+ return target;
+}
+
+/* Convert a wide character string to the UCS-4 encoded string. This
+ is necessary on systems where internal form of wchar_t are not Unicode
+ code points (e.g. Oracle Solaris).
+
+ Return a pointer to a newly allocated string, use PyMem_Free() to free
+ the memory. Return NULL and raise exception on conversion or memory
+ allocation error. */
+wchar_t *
+_Py_DecodeNonUnicodeWchar(const wchar_t *native, Py_ssize_t size)
+{
+ return _Py_ConvertWCharForm(native, size, "UCS-4-INTERNAL", "wchar_t");
+}
+
+/* Convert a UCS-4 encoded string to native wide character string. This
+ is necessary on systems where internal form of wchar_t are not Unicode
+ code points (e.g. Oracle Solaris).
+
+ The conversion is done in place. This can be done because both wchar_t
+ and UCS-4 use 4-byte encoding, and one wchar_t symbol always correspond
+ to a single UCS-4 symbol and vice versa. (This is true for Oracle Solaris,
+ which is currently the only system using these functions; it doesn't have
+ to be for other systems).
+
+ Return 0 on success. Return -1 and raise exception on conversion
+ or memory allocation error. */
+int
+_Py_EncodeNonUnicodeWchar_InPlace(wchar_t *unicode, Py_ssize_t size)
+{
+ wchar_t* result = _Py_ConvertWCharForm(unicode, size, "wchar_t", "UCS-4-INTERNAL");
+ if (!result) {
+ return -1;
+ }
+ memcpy(unicode, result, size * sizeof(wchar_t));
+ PyMem_Free(result);
+ return 0;
+}
+#endif /* HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION */
+
+#ifdef MS_WINDOWS
+static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
+
+static void
+FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
+{
+ /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
+ /* Cannot simply cast and dereference in_ptr,
+ since it might not be aligned properly */
+ __int64 in;
+ memcpy(&in, in_ptr, sizeof(in));
+ *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
+ *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
+}
+
+void
+_Py_time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
+{
+ /* XXX endianness */
+ __int64 out;
+ out = time_in + secs_between_epochs;
+ out = out * 10000000 + nsec_in / 100;
+ memcpy(out_ptr, &out, sizeof(out));
+}
+
+/* Below, we *know* that ugo+r is 0444 */
+#if _S_IREAD != 0400
+#error Unsupported C library
+#endif
+static int
+attributes_to_mode(DWORD attr)
+{
+ int m = 0;
+ if (attr & FILE_ATTRIBUTE_DIRECTORY)
+ m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
+ else
+ m |= _S_IFREG;
+ if (attr & FILE_ATTRIBUTE_READONLY)
+ m |= 0444;
+ else
+ m |= 0666;
+ return m;
+}
+
+void
+_Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag,
+ struct _Py_stat_struct *result)
+{
+ memset(result, 0, sizeof(*result));
+ result->st_mode = attributes_to_mode(info->dwFileAttributes);
+ result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
+ result->st_dev = info->dwVolumeSerialNumber;
+ result->st_rdev = result->st_dev;
+ FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
+ FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
+ FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
+ result->st_nlink = info->nNumberOfLinks;
+ result->st_ino = (((uint64_t)info->nFileIndexHigh) << 32) + info->nFileIndexLow;
+ /* bpo-37834: Only actual symlinks set the S_IFLNK flag. But lstat() will
+ open other name surrogate reparse points without traversing them. To
+ detect/handle these, check st_file_attributes and st_reparse_tag. */
+ result->st_reparse_tag = reparse_tag;
+ if (info->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT &&
+ reparse_tag == IO_REPARSE_TAG_SYMLINK) {
+ /* first clear the S_IFMT bits */
+ result->st_mode ^= (result->st_mode & S_IFMT);
+ /* now set the bits that make this a symlink */
+ result->st_mode |= S_IFLNK;
+ }
+ result->st_file_attributes = info->dwFileAttributes;
+}
+#endif
+
+/* Return information about a file.
+
+ On POSIX, use fstat().
+
+ On Windows, use GetFileType() and GetFileInformationByHandle() which support
+ files larger than 2 GiB. fstat() may fail with EOVERFLOW on files larger
+ than 2 GiB because the file size type is a signed 32-bit integer: see issue
+ #23152.
+
+ On Windows, set the last Windows error and return nonzero on error. On
+ POSIX, set errno and return nonzero on error. Fill status and return 0 on
+ success. */
+int
+_Py_fstat_noraise(int fd, struct _Py_stat_struct *status)
+{
+#ifdef MS_WINDOWS
+ BY_HANDLE_FILE_INFORMATION info;
+ HANDLE h;
+ int type;
+
+ _Py_BEGIN_SUPPRESS_IPH
+ h = (HANDLE)_get_osfhandle(fd);
+ _Py_END_SUPPRESS_IPH
+
+ if (h == INVALID_HANDLE_VALUE) {
+ /* errno is already set by _get_osfhandle, but we also set
+ the Win32 error for callers who expect that */
+ SetLastError(ERROR_INVALID_HANDLE);
+ return -1;
+ }
+ memset(status, 0, sizeof(*status));
+
+ type = GetFileType(h);
+ if (type == FILE_TYPE_UNKNOWN) {
+ DWORD error = GetLastError();
+ if (error != 0) {
+ errno = winerror_to_errno(error);
+ return -1;
+ }
+ /* else: valid but unknown file */
+ }
+
+ if (type != FILE_TYPE_DISK) {
+ if (type == FILE_TYPE_CHAR)
+ status->st_mode = _S_IFCHR;
+ else if (type == FILE_TYPE_PIPE)
+ status->st_mode = _S_IFIFO;
+ return 0;
+ }
+
+ if (!GetFileInformationByHandle(h, &info)) {
+ /* The Win32 error is already set, but we also set errno for
+ callers who expect it */
+ errno = winerror_to_errno(GetLastError());
+ return -1;
+ }
+
+ _Py_attribute_data_to_stat(&info, 0, status);
+ /* specific to fstat() */
+ status->st_ino = (((uint64_t)info.nFileIndexHigh) << 32) + info.nFileIndexLow;
+ return 0;
+#else
+ return fstat(fd, status);
+#endif
+}
+
+/* Return information about a file.
+
+ On POSIX, use fstat().
+
+ On Windows, use GetFileType() and GetFileInformationByHandle() which support
+ files larger than 2 GiB. fstat() may fail with EOVERFLOW on files larger
+ than 2 GiB because the file size type is a signed 32-bit integer: see issue
+ #23152.
+
+ Raise an exception and return -1 on error. On Windows, set the last Windows
+ error on error. On POSIX, set errno on error. Fill status and return 0 on
+ success.
+
+ Release the GIL to call GetFileType() and GetFileInformationByHandle(), or
+ to call fstat(). The caller must hold the GIL. */
+int
+_Py_fstat(int fd, struct _Py_stat_struct *status)
+{
+ int res;
+
+ assert(PyGILState_Check());
+
+ Py_BEGIN_ALLOW_THREADS
+ res = _Py_fstat_noraise(fd, status);
+ Py_END_ALLOW_THREADS
+
+ if (res != 0) {
+#ifdef MS_WINDOWS
+ PyErr_SetFromWindowsErr(0);
+#else
+ PyErr_SetFromErrno(PyExc_OSError);
+#endif
+ return -1;
+ }
+ return 0;
+}
+
+/* Call _wstat() on Windows, or encode the path to the filesystem encoding and
+ call stat() otherwise. Only fill st_mode attribute on Windows.
+
+ Return 0 on success, -1 on _wstat() / stat() error, -2 if an exception was
+ raised. */
+
+int
+_Py_stat(PyObject *path, struct stat *statbuf)
+{
+#ifdef MS_WINDOWS
+ int err;
+ struct _stat wstatbuf;
+ const wchar_t *wpath;
+
+_Py_COMP_DIAG_PUSH
+_Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ wpath = _PyUnicode_AsUnicode(path);
+_Py_COMP_DIAG_POP
+ if (wpath == NULL)
+ return -2;
+
+ err = _wstat(wpath, &wstatbuf);
+ if (!err)
+ statbuf->st_mode = wstatbuf.st_mode;
+ return err;
+#else
+ int ret;
+ PyObject *bytes;
+ char *cpath;
+
+ bytes = PyUnicode_EncodeFSDefault(path);
+ if (bytes == NULL)
+ return -2;
+
+ /* check for embedded null bytes */
+ if (PyBytes_AsStringAndSize(bytes, &cpath, NULL) == -1) {
+ Py_DECREF(bytes);
+ return -2;
+ }
+
+ ret = stat(cpath, statbuf);
+ Py_DECREF(bytes);
+ return ret;
+#endif
+}
+
+
+/* This function MUST be kept async-signal-safe on POSIX when raise=0. */
+static int
+get_inheritable(int fd, int raise)
+{
+#ifdef MS_WINDOWS
+ HANDLE handle;
+ DWORD flags;
+
+ _Py_BEGIN_SUPPRESS_IPH
+ handle = (HANDLE)_get_osfhandle(fd);
+ _Py_END_SUPPRESS_IPH
+ if (handle == INVALID_HANDLE_VALUE) {
+ if (raise)
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+
+ if (!GetHandleInformation(handle, &flags)) {
+ if (raise)
+ PyErr_SetFromWindowsErr(0);
+ return -1;
+ }
+
+ return (flags & HANDLE_FLAG_INHERIT);
+#else
+ int flags;
+
+ flags = fcntl(fd, F_GETFD, 0);
+ if (flags == -1) {
+ if (raise)
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+ return !(flags & FD_CLOEXEC);
+#endif
+}
+
+/* Get the inheritable flag of the specified file descriptor.
+ Return 1 if the file descriptor can be inherited, 0 if it cannot,
+ raise an exception and return -1 on error. */
+int
+_Py_get_inheritable(int fd)
+{
+ return get_inheritable(fd, 1);
+}
+
+
+/* This function MUST be kept async-signal-safe on POSIX when raise=0. */
+static int
+set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works)
+{
+#ifdef MS_WINDOWS
+ HANDLE handle;
+ DWORD flags;
+#else
+#if defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX)
+ static int ioctl_works = -1;
+ int request;
+ int err;
+#endif
+ int flags, new_flags;
+ int res;
+#endif
+
+ /* atomic_flag_works can only be used to make the file descriptor
+ non-inheritable */
+ assert(!(atomic_flag_works != NULL && inheritable));
+
+ if (atomic_flag_works != NULL && !inheritable) {
+ if (*atomic_flag_works == -1) {
+ int isInheritable = get_inheritable(fd, raise);
+ if (isInheritable == -1)
+ return -1;
+ *atomic_flag_works = !isInheritable;
+ }
+
+ if (*atomic_flag_works)
+ return 0;
+ }
+
+#ifdef MS_WINDOWS
+ _Py_BEGIN_SUPPRESS_IPH
+ handle = (HANDLE)_get_osfhandle(fd);
+ _Py_END_SUPPRESS_IPH
+ if (handle == INVALID_HANDLE_VALUE) {
+ if (raise)
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+
+ if (inheritable)
+ flags = HANDLE_FLAG_INHERIT;
+ else
+ flags = 0;
+
+ /* This check can be removed once support for Windows 7 ends. */
+#define CONSOLE_PSEUDOHANDLE(handle) (((ULONG_PTR)(handle) & 0x3) == 0x3 && \
+ GetFileType(handle) == FILE_TYPE_CHAR)
+
+ if (!CONSOLE_PSEUDOHANDLE(handle) &&
+ !SetHandleInformation(handle, HANDLE_FLAG_INHERIT, flags)) {
+ if (raise)
+ PyErr_SetFromWindowsErr(0);
+ return -1;
+ }
+#undef CONSOLE_PSEUDOHANDLE
+ return 0;
+
+#else
+
+#if defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX)
+ if (ioctl_works != 0 && raise != 0) {
+ /* fast-path: ioctl() only requires one syscall */
+ /* caveat: raise=0 is an indicator that we must be async-signal-safe
+ * thus avoid using ioctl() so we skip the fast-path. */
+ if (inheritable)
+ request = FIONCLEX;
+ else
+ request = FIOCLEX;
+ err = ioctl(fd, request, NULL);
+ if (!err) {
+ ioctl_works = 1;
+ return 0;
+ }
+
+#ifdef O_PATH
+ if (errno == EBADF) {
+ // bpo-44849: On Linux and FreeBSD, ioctl(FIOCLEX) fails with EBADF
+ // on O_PATH file descriptors. Fall through to the fcntl()
+ // implementation.
+ }
+ else
+#endif
+ if (errno != ENOTTY && errno != EACCES) {
+ if (raise)
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+ else {
+ /* Issue #22258: Here, ENOTTY means "Inappropriate ioctl for
+ device". The ioctl is declared but not supported by the kernel.
+ Remember that ioctl() doesn't work. It is the case on
+ Illumos-based OS for example.
+
+ Issue #27057: When SELinux policy disallows ioctl it will fail
+ with EACCES. While FIOCLEX is safe operation it may be
+ unavailable because ioctl was denied altogether.
+ This can be the case on Android. */
+ ioctl_works = 0;
+ }
+ /* fallback to fcntl() if ioctl() does not work */
+ }
+#endif
+
+ /* slow-path: fcntl() requires two syscalls */
+ flags = fcntl(fd, F_GETFD);
+ if (flags < 0) {
+ if (raise)
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+
+ if (inheritable) {
+ new_flags = flags & ~FD_CLOEXEC;
+ }
+ else {
+ new_flags = flags | FD_CLOEXEC;
+ }
+
+ if (new_flags == flags) {
+ /* FD_CLOEXEC flag already set/cleared: nothing to do */
+ return 0;
+ }
+
+ res = fcntl(fd, F_SETFD, new_flags);
+ if (res < 0) {
+ if (raise)
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+ return 0;
+#endif
+}
+
+/* Make the file descriptor non-inheritable.
+ Return 0 on success, set errno and return -1 on error. */
+static int
+make_non_inheritable(int fd)
+{
+ return set_inheritable(fd, 0, 0, NULL);
+}
+
+/* Set the inheritable flag of the specified file descriptor.
+ On success: return 0, on error: raise an exception and return -1.
+
+ If atomic_flag_works is not NULL:
+
+ * if *atomic_flag_works==-1, check if the inheritable is set on the file
+ descriptor: if yes, set *atomic_flag_works to 1, otherwise set to 0 and
+ set the inheritable flag
+ * if *atomic_flag_works==1: do nothing
+ * if *atomic_flag_works==0: set inheritable flag to False
+
+ Set atomic_flag_works to NULL if no atomic flag was used to create the
+ file descriptor.
+
+ atomic_flag_works can only be used to make a file descriptor
+ non-inheritable: atomic_flag_works must be NULL if inheritable=1. */
+int
+_Py_set_inheritable(int fd, int inheritable, int *atomic_flag_works)
+{
+ return set_inheritable(fd, inheritable, 1, atomic_flag_works);
+}
+
+/* Same as _Py_set_inheritable() but on error, set errno and
+ don't raise an exception.
+ This function is async-signal-safe. */
+int
+_Py_set_inheritable_async_safe(int fd, int inheritable, int *atomic_flag_works)
+{
+ return set_inheritable(fd, inheritable, 0, atomic_flag_works);
+}
+
+static int
+_Py_open_impl(const char *pathname, int flags, int gil_held)
+{
+ int fd;
+ int async_err = 0;
+#ifndef MS_WINDOWS
+ int *atomic_flag_works;
+#endif
+
+#ifdef MS_WINDOWS
+ flags |= O_NOINHERIT;
+#elif defined(O_CLOEXEC)
+ atomic_flag_works = &_Py_open_cloexec_works;
+ flags |= O_CLOEXEC;
+#else
+ atomic_flag_works = NULL;
+#endif
+
+ if (gil_held) {
+ PyObject *pathname_obj = PyUnicode_DecodeFSDefault(pathname);
+ if (pathname_obj == NULL) {
+ return -1;
+ }
+ if (PySys_Audit("open", "OOi", pathname_obj, Py_None, flags) < 0) {
+ Py_DECREF(pathname_obj);
+ return -1;
+ }
+
+ do {
+ Py_BEGIN_ALLOW_THREADS
+ fd = open(pathname, flags);
+ Py_END_ALLOW_THREADS
+ } while (fd < 0
+ && errno == EINTR && !(async_err = PyErr_CheckSignals()));
+ if (async_err) {
+ Py_DECREF(pathname_obj);
+ return -1;
+ }
+ if (fd < 0) {
+ PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, pathname_obj, NULL);
+ Py_DECREF(pathname_obj);
+ return -1;
+ }
+ Py_DECREF(pathname_obj);
+ }
+ else {
+ fd = open(pathname, flags);
+ if (fd < 0)
+ return -1;
+ }
+
+#ifndef MS_WINDOWS
+ if (set_inheritable(fd, 0, gil_held, atomic_flag_works) < 0) {
+ close(fd);
+ return -1;
+ }
+#endif
+
+ return fd;
+}
+
+/* Open a file with the specified flags (wrapper to open() function).
+ Return a file descriptor on success. Raise an exception and return -1 on
+ error.
+
+ The file descriptor is created non-inheritable.
+
+ When interrupted by a signal (open() fails with EINTR), retry the syscall,
+ except if the Python signal handler raises an exception.
+
+ Release the GIL to call open(). The caller must hold the GIL. */
+int
+_Py_open(const char *pathname, int flags)
+{
+ /* _Py_open() must be called with the GIL held. */
+ assert(PyGILState_Check());
+ return _Py_open_impl(pathname, flags, 1);
+}
+
+/* Open a file with the specified flags (wrapper to open() function).
+ Return a file descriptor on success. Set errno and return -1 on error.
+
+ The file descriptor is created non-inheritable.
+
+ If interrupted by a signal, fail with EINTR. */
+int
+_Py_open_noraise(const char *pathname, int flags)
+{
+ return _Py_open_impl(pathname, flags, 0);
+}
+
+/* Open a file. Use _wfopen() on Windows, encode the path to the locale
+ encoding and use fopen() otherwise.
+
+ The file descriptor is created non-inheritable.
+
+ If interrupted by a signal, fail with EINTR. */
+FILE *
+_Py_wfopen(const wchar_t *path, const wchar_t *mode)
+{
+ FILE *f;
+ if (PySys_Audit("open", "uui", path, mode, 0) < 0) {
+ return NULL;
+ }
+#ifndef MS_WINDOWS
+ char *cpath;
+ char cmode[10];
+ size_t r;
+ r = wcstombs(cmode, mode, 10);
+ if (r == DECODE_ERROR || r >= 10) {
+ errno = EINVAL;
+ return NULL;
+ }
+ cpath = _Py_EncodeLocaleRaw(path, NULL);
+ if (cpath == NULL) {
+ return NULL;
+ }
+ f = fopen(cpath, cmode);
+ PyMem_RawFree(cpath);
+#else
+ f = _wfopen(path, mode);
+#endif
+ if (f == NULL)
+ return NULL;
+ if (make_non_inheritable(fileno(f)) < 0) {
+ fclose(f);
+ return NULL;
+ }
+ return f;
+}
+
+/* Wrapper to fopen().
+
+ The file descriptor is created non-inheritable.
+
+ If interrupted by a signal, fail with EINTR. */
+FILE*
+_Py_fopen(const char *pathname, const char *mode)
+{
+ PyObject *pathname_obj = PyUnicode_DecodeFSDefault(pathname);
+ if (pathname_obj == NULL) {
+ return NULL;
+ }
+ if (PySys_Audit("open", "Osi", pathname_obj, mode, 0) < 0) {
+ Py_DECREF(pathname_obj);
+ return NULL;
+ }
+ Py_DECREF(pathname_obj);
+
+ FILE *f = fopen(pathname, mode);
+ if (f == NULL)
+ return NULL;
+ if (make_non_inheritable(fileno(f)) < 0) {
+ fclose(f);
+ return NULL;
+ }
+ return f;
+}
+
+/* Open a file. Call _wfopen() on Windows, or encode the path to the filesystem
+ encoding and call fopen() otherwise.
+
+ Return the new file object on success. Raise an exception and return NULL
+ on error.
+
+ The file descriptor is created non-inheritable.
+
+ When interrupted by a signal (open() fails with EINTR), retry the syscall,
+ except if the Python signal handler raises an exception.
+
+ Release the GIL to call _wfopen() or fopen(). The caller must hold
+ the GIL. */
+FILE*
+_Py_fopen_obj(PyObject *path, const char *mode)
+{
+ FILE *f;
+ int async_err = 0;
+#ifdef MS_WINDOWS
+ const wchar_t *wpath;
+ wchar_t wmode[10];
+ int usize;
+
+ assert(PyGILState_Check());
+
+ if (PySys_Audit("open", "Osi", path, mode, 0) < 0) {
+ return NULL;
+ }
+ if (!PyUnicode_Check(path)) {
+ PyErr_Format(PyExc_TypeError,
+ "str file path expected under Windows, got %R",
+ Py_TYPE(path));
+ return NULL;
+ }
+_Py_COMP_DIAG_PUSH
+_Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ wpath = _PyUnicode_AsUnicode(path);
+_Py_COMP_DIAG_POP
+ if (wpath == NULL)
+ return NULL;
+
+ usize = MultiByteToWideChar(CP_ACP, 0, mode, -1,
+ wmode, Py_ARRAY_LENGTH(wmode));
+ if (usize == 0) {
+ PyErr_SetFromWindowsErr(0);
+ return NULL;
+ }
+
+ do {
+ Py_BEGIN_ALLOW_THREADS
+ f = _wfopen(wpath, wmode);
+ Py_END_ALLOW_THREADS
+ } while (f == NULL
+ && errno == EINTR && !(async_err = PyErr_CheckSignals()));
+#else
+ PyObject *bytes;
+ const char *path_bytes;
+
+ assert(PyGILState_Check());
+
+ if (!PyUnicode_FSConverter(path, &bytes))
+ return NULL;
+ path_bytes = PyBytes_AS_STRING(bytes);
+
+ if (PySys_Audit("open", "Osi", path, mode, 0) < 0) {
+ Py_DECREF(bytes);
+ return NULL;
+ }
+
+ do {
+ Py_BEGIN_ALLOW_THREADS
+ f = fopen(path_bytes, mode);
+ Py_END_ALLOW_THREADS
+ } while (f == NULL
+ && errno == EINTR && !(async_err = PyErr_CheckSignals()));
+
+ Py_DECREF(bytes);
+#endif
+ if (async_err)
+ return NULL;
+
+ if (f == NULL) {
+ PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
+ return NULL;
+ }
+
+ if (set_inheritable(fileno(f), 0, 1, NULL) < 0) {
+ fclose(f);
+ return NULL;
+ }
+ return f;
+}
+
+/* Read count bytes from fd into buf.
+
+ On success, return the number of read bytes, it can be lower than count.
+ If the current file offset is at or past the end of file, no bytes are read,
+ and read() returns zero.
+
+ On error, raise an exception, set errno and return -1.
+
+ When interrupted by a signal (read() fails with EINTR), retry the syscall.
+ If the Python signal handler raises an exception, the function returns -1
+ (the syscall is not retried).
+
+ Release the GIL to call read(). The caller must hold the GIL. */
+Py_ssize_t
+_Py_read(int fd, void *buf, size_t count)
+{
+ Py_ssize_t n;
+ int err;
+ int async_err = 0;
+
+ assert(PyGILState_Check());
+
+ /* _Py_read() must not be called with an exception set, otherwise the
+ * caller may think that read() was interrupted by a signal and the signal
+ * handler raised an exception. */
+ assert(!PyErr_Occurred());
+
+ if (count > _PY_READ_MAX) {
+ count = _PY_READ_MAX;
+ }
+
+ _Py_BEGIN_SUPPRESS_IPH
+ do {
+ Py_BEGIN_ALLOW_THREADS
+ errno = 0;
+#ifdef MS_WINDOWS
+ n = read(fd, buf, (int)count);
+#else
+ n = read(fd, buf, count);
+#endif
+ /* save/restore errno because PyErr_CheckSignals()
+ * and PyErr_SetFromErrno() can modify it */
+ err = errno;
+ Py_END_ALLOW_THREADS
+ } while (n < 0 && err == EINTR &&
+ !(async_err = PyErr_CheckSignals()));
+ _Py_END_SUPPRESS_IPH
+
+ if (async_err) {
+ /* read() was interrupted by a signal (failed with EINTR)
+ * and the Python signal handler raised an exception */
+ errno = err;
+ assert(errno == EINTR && PyErr_Occurred());
+ return -1;
+ }
+ if (n < 0) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ errno = err;
+ return -1;
+ }
+
+ return n;
+}
+
+static Py_ssize_t
+_Py_write_impl(int fd, const void *buf, size_t count, int gil_held)
+{
+ Py_ssize_t n;
+ int err;
+ int async_err = 0;
+
+ _Py_BEGIN_SUPPRESS_IPH
+#ifdef MS_WINDOWS
+ if (count > 32767) {
+ /* Issue #11395: the Windows console returns an error (12: not
+ enough space error) on writing into stdout if stdout mode is
+ binary and the length is greater than 66,000 bytes (or less,
+ depending on heap usage). */
+ if (gil_held) {
+ Py_BEGIN_ALLOW_THREADS
+ if (isatty(fd)) {
+ count = 32767;
+ }
+ Py_END_ALLOW_THREADS
+ } else {
+ if (isatty(fd)) {
+ count = 32767;
+ }
+ }
+ }
+#endif
+ if (count > _PY_WRITE_MAX) {
+ count = _PY_WRITE_MAX;
+ }
+
+ if (gil_held) {
+ do {
+ Py_BEGIN_ALLOW_THREADS
+ errno = 0;
+#ifdef MS_WINDOWS
+ n = write(fd, buf, (int)count);
+#else
+ n = write(fd, buf, count);
+#endif
+ /* save/restore errno because PyErr_CheckSignals()
+ * and PyErr_SetFromErrno() can modify it */
+ err = errno;
+ Py_END_ALLOW_THREADS
+ } while (n < 0 && err == EINTR &&
+ !(async_err = PyErr_CheckSignals()));
+ }
+ else {
+ do {
+ errno = 0;
+#ifdef MS_WINDOWS
+ n = write(fd, buf, (int)count);
+#else
+ n = write(fd, buf, count);
+#endif
+ err = errno;
+ } while (n < 0 && err == EINTR);
+ }
+ _Py_END_SUPPRESS_IPH
+
+ if (async_err) {
+ /* write() was interrupted by a signal (failed with EINTR)
+ and the Python signal handler raised an exception (if gil_held is
+ nonzero). */
+ errno = err;
+ assert(errno == EINTR && (!gil_held || PyErr_Occurred()));
+ return -1;
+ }
+ if (n < 0) {
+ if (gil_held)
+ PyErr_SetFromErrno(PyExc_OSError);
+ errno = err;
+ return -1;
+ }
+
+ return n;
+}
+
+/* Write count bytes of buf into fd.
+
+ On success, return the number of written bytes, it can be lower than count
+ including 0. On error, raise an exception, set errno and return -1.
+
+ When interrupted by a signal (write() fails with EINTR), retry the syscall.
+ If the Python signal handler raises an exception, the function returns -1
+ (the syscall is not retried).
+
+ Release the GIL to call write(). The caller must hold the GIL. */
+Py_ssize_t
+_Py_write(int fd, const void *buf, size_t count)
+{
+ assert(PyGILState_Check());
+
+ /* _Py_write() must not be called with an exception set, otherwise the
+ * caller may think that write() was interrupted by a signal and the signal
+ * handler raised an exception. */
+ assert(!PyErr_Occurred());
+
+ return _Py_write_impl(fd, buf, count, 1);
+}
+
+/* Write count bytes of buf into fd.
+ *
+ * On success, return the number of written bytes, it can be lower than count
+ * including 0. On error, set errno and return -1.
+ *
+ * When interrupted by a signal (write() fails with EINTR), retry the syscall
+ * without calling the Python signal handler. */
+Py_ssize_t
+_Py_write_noraise(int fd, const void *buf, size_t count)
+{
+ return _Py_write_impl(fd, buf, count, 0);
+}
+
+#ifdef HAVE_READLINK
+
+/* Read value of symbolic link. Encode the path to the locale encoding, decode
+ the result from the locale encoding.
+
+ Return -1 on encoding error, on readlink() error, if the internal buffer is
+ too short, on decoding error, or if 'buf' is too short. */
+int
+_Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t buflen)
+{
+ char *cpath;
+ char cbuf[MAXPATHLEN];
+ size_t cbuf_len = Py_ARRAY_LENGTH(cbuf);
+ wchar_t *wbuf;
+ Py_ssize_t res;
+ size_t r1;
+
+ cpath = _Py_EncodeLocaleRaw(path, NULL);
+ if (cpath == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+ res = readlink(cpath, cbuf, cbuf_len);
+ PyMem_RawFree(cpath);
+ if (res == -1) {
+ return -1;
+ }
+ if ((size_t)res == cbuf_len) {
+ errno = EINVAL;
+ return -1;
+ }
+ cbuf[res] = '\0'; /* buf will be null terminated */
+ wbuf = Py_DecodeLocale(cbuf, &r1);
+ if (wbuf == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+ /* wbuf must have space to store the trailing NUL character */
+ if (buflen <= r1) {
+ PyMem_RawFree(wbuf);
+ errno = EINVAL;
+ return -1;
+ }
+ wcsncpy(buf, wbuf, buflen);
+ PyMem_RawFree(wbuf);
+ return (int)r1;
+}
+#endif
+
+#ifdef HAVE_REALPATH
+
+/* Return the canonicalized absolute pathname. Encode path to the locale
+ encoding, decode the result from the locale encoding.
+
+ Return NULL on encoding error, realpath() error, decoding error
+ or if 'resolved_path' is too short. */
+wchar_t*
+_Py_wrealpath(const wchar_t *path,
+ wchar_t *resolved_path, size_t resolved_path_len)
+{
+ char *cpath;
+ char cresolved_path[MAXPATHLEN];
+ wchar_t *wresolved_path;
+ char *res;
+ size_t r;
+ cpath = _Py_EncodeLocaleRaw(path, NULL);
+ if (cpath == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+ res = realpath(cpath, cresolved_path);
+ PyMem_RawFree(cpath);
+ if (res == NULL)
+ return NULL;
+
+ wresolved_path = Py_DecodeLocale(cresolved_path, &r);
+ if (wresolved_path == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+ /* wresolved_path must have space to store the trailing NUL character */
+ if (resolved_path_len <= r) {
+ PyMem_RawFree(wresolved_path);
+ errno = EINVAL;
+ return NULL;
+ }
+ wcsncpy(resolved_path, wresolved_path, resolved_path_len);
+ PyMem_RawFree(wresolved_path);
+ return resolved_path;
+}
+#endif
+
+
+#ifndef MS_WINDOWS
+int
+_Py_isabs(const wchar_t *path)
+{
+ return (path[0] == SEP);
+}
+#endif
+
+
+/* Get an absolute path.
+ On error (ex: fail to get the current directory), return -1.
+ On memory allocation failure, set *abspath_p to NULL and return 0.
+ On success, return a newly allocated to *abspath_p to and return 0.
+ The string must be freed by PyMem_RawFree(). */
+int
+_Py_abspath(const wchar_t *path, wchar_t **abspath_p)
+{
+#ifdef MS_WINDOWS
+ wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
+ DWORD result;
+
+ result = GetFullPathNameW(path,
+ Py_ARRAY_LENGTH(woutbuf), woutbuf,
+ NULL);
+ if (!result) {
+ return -1;
+ }
+
+ if (result > Py_ARRAY_LENGTH(woutbuf)) {
+ if ((size_t)result <= (size_t)PY_SSIZE_T_MAX / sizeof(wchar_t)) {
+ woutbufp = PyMem_RawMalloc((size_t)result * sizeof(wchar_t));
+ }
+ else {
+ woutbufp = NULL;
+ }
+ if (!woutbufp) {
+ *abspath_p = NULL;
+ return 0;
+ }
+
+ result = GetFullPathNameW(path, result, woutbufp, NULL);
+ if (!result) {
+ PyMem_RawFree(woutbufp);
+ return -1;
+ }
+ }
+
+ if (woutbufp != woutbuf) {
+ *abspath_p = woutbufp;
+ return 0;
+ }
+
+ *abspath_p = _PyMem_RawWcsdup(woutbufp);
+ return 0;
+#else
+ if (_Py_isabs(path)) {
+ *abspath_p = _PyMem_RawWcsdup(path);
+ return 0;
+ }
+
+ wchar_t cwd[MAXPATHLEN + 1];
+ cwd[Py_ARRAY_LENGTH(cwd) - 1] = 0;
+ if (!_Py_wgetcwd(cwd, Py_ARRAY_LENGTH(cwd) - 1)) {
+ /* unable to get the current directory */
+ return -1;
+ }
+
+ size_t cwd_len = wcslen(cwd);
+ size_t path_len = wcslen(path);
+ size_t len = cwd_len + 1 + path_len + 1;
+ if (len <= (size_t)PY_SSIZE_T_MAX / sizeof(wchar_t)) {
+ *abspath_p = PyMem_RawMalloc(len * sizeof(wchar_t));
+ }
+ else {
+ *abspath_p = NULL;
+ }
+ if (*abspath_p == NULL) {
+ return 0;
+ }
+
+ wchar_t *abspath = *abspath_p;
+ memcpy(abspath, cwd, cwd_len * sizeof(wchar_t));
+ abspath += cwd_len;
+
+ *abspath = (wchar_t)SEP;
+ abspath++;
+
+ memcpy(abspath, path, path_len * sizeof(wchar_t));
+ abspath += path_len;
+
+ *abspath = 0;
+ return 0;
+#endif
+}
+
+
+/* Get the current directory. buflen is the buffer size in wide characters
+ including the null character. Decode the path from the locale encoding.
+
+ Return NULL on getcwd() error, on decoding error, or if 'buf' is
+ too short. */
+wchar_t*
+_Py_wgetcwd(wchar_t *buf, size_t buflen)
+{
+#ifdef MS_WINDOWS
+ int ibuflen = (int)Py_MIN(buflen, INT_MAX);
+ return _wgetcwd(buf, ibuflen);
+#else
+ char fname[MAXPATHLEN];
+ wchar_t *wname;
+ size_t len;
+
+ if (getcwd(fname, Py_ARRAY_LENGTH(fname)) == NULL)
+ return NULL;
+ wname = Py_DecodeLocale(fname, &len);
+ if (wname == NULL)
+ return NULL;
+ /* wname must have space to store the trailing NUL character */
+ if (buflen <= len) {
+ PyMem_RawFree(wname);
+ return NULL;
+ }
+ wcsncpy(buf, wname, buflen);
+ PyMem_RawFree(wname);
+ return buf;
+#endif
+}
+
+/* Duplicate a file descriptor. The new file descriptor is created as
+ non-inheritable. Return a new file descriptor on success, raise an OSError
+ exception and return -1 on error.
+
+ The GIL is released to call dup(). The caller must hold the GIL. */
+int
+_Py_dup(int fd)
+{
+#ifdef MS_WINDOWS
+ HANDLE handle;
+#endif
+
+ assert(PyGILState_Check());
+
+#ifdef MS_WINDOWS
+ _Py_BEGIN_SUPPRESS_IPH
+ handle = (HANDLE)_get_osfhandle(fd);
+ _Py_END_SUPPRESS_IPH
+ if (handle == INVALID_HANDLE_VALUE) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ _Py_BEGIN_SUPPRESS_IPH
+ fd = dup(fd);
+ _Py_END_SUPPRESS_IPH
+ Py_END_ALLOW_THREADS
+ if (fd < 0) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+
+ if (_Py_set_inheritable(fd, 0, NULL) < 0) {
+ _Py_BEGIN_SUPPRESS_IPH
+ close(fd);
+ _Py_END_SUPPRESS_IPH
+ return -1;
+ }
+#elif defined(HAVE_FCNTL_H) && defined(F_DUPFD_CLOEXEC)
+ Py_BEGIN_ALLOW_THREADS
+ _Py_BEGIN_SUPPRESS_IPH
+ fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
+ _Py_END_SUPPRESS_IPH
+ Py_END_ALLOW_THREADS
+ if (fd < 0) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+
+#else
+ Py_BEGIN_ALLOW_THREADS
+ _Py_BEGIN_SUPPRESS_IPH
+ fd = dup(fd);
+ _Py_END_SUPPRESS_IPH
+ Py_END_ALLOW_THREADS
+ if (fd < 0) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+
+ if (_Py_set_inheritable(fd, 0, NULL) < 0) {
+ _Py_BEGIN_SUPPRESS_IPH
+ close(fd);
+ _Py_END_SUPPRESS_IPH
+ return -1;
+ }
+#endif
+ return fd;
+}
+
+#ifndef MS_WINDOWS
+/* Get the blocking mode of the file descriptor.
+ Return 0 if the O_NONBLOCK flag is set, 1 if the flag is cleared,
+ raise an exception and return -1 on error. */
+int
+_Py_get_blocking(int fd)
+{
+ int flags;
+ _Py_BEGIN_SUPPRESS_IPH
+ flags = fcntl(fd, F_GETFL, 0);
+ _Py_END_SUPPRESS_IPH
+ if (flags < 0) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+
+ return !(flags & O_NONBLOCK);
+}
+
+/* Set the blocking mode of the specified file descriptor.
+
+ Set the O_NONBLOCK flag if blocking is False, clear the O_NONBLOCK flag
+ otherwise.
+
+ Return 0 on success, raise an exception and return -1 on error. */
+int
+_Py_set_blocking(int fd, int blocking)
+{
+#if defined(HAVE_SYS_IOCTL_H) && defined(FIONBIO)
+ int arg = !blocking;
+ if (ioctl(fd, FIONBIO, &arg) < 0)
+ goto error;
+#else
+ int flags, res;
+
+ _Py_BEGIN_SUPPRESS_IPH
+ flags = fcntl(fd, F_GETFL, 0);
+ if (flags >= 0) {
+ if (blocking)
+ flags = flags & (~O_NONBLOCK);
+ else
+ flags = flags | O_NONBLOCK;
+
+ res = fcntl(fd, F_SETFL, flags);
+ } else {
+ res = -1;
+ }
+ _Py_END_SUPPRESS_IPH
+
+ if (res < 0)
+ goto error;
+#endif
+ return 0;
+
+error:
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+}
+#endif
+
+
+int
+_Py_GetLocaleconvNumeric(struct lconv *lc,
+ PyObject **decimal_point, PyObject **thousands_sep)
+{
+ assert(decimal_point != NULL);
+ assert(thousands_sep != NULL);
+
+#ifndef MS_WINDOWS
+ int change_locale = 0;
+ if ((strlen(lc->decimal_point) > 1 || ((unsigned char)lc->decimal_point[0]) > 127)) {
+ change_locale = 1;
+ }
+ if ((strlen(lc->thousands_sep) > 1 || ((unsigned char)lc->thousands_sep[0]) > 127)) {
+ change_locale = 1;
+ }
+
+ /* Keep a copy of the LC_CTYPE locale */
+ char *oldloc = NULL, *loc = NULL;
+ if (change_locale) {
+ oldloc = setlocale(LC_CTYPE, NULL);
+ if (!oldloc) {
+ PyErr_SetString(PyExc_RuntimeWarning,
+ "failed to get LC_CTYPE locale");
+ return -1;
+ }
+
+ oldloc = _PyMem_Strdup(oldloc);
+ if (!oldloc) {
+ PyErr_NoMemory();
+ return -1;
+ }
+
+ loc = setlocale(LC_NUMERIC, NULL);
+ if (loc != NULL && strcmp(loc, oldloc) == 0) {
+ loc = NULL;
+ }
+
+ if (loc != NULL) {
+ /* Only set the locale temporarily the LC_CTYPE locale
+ if LC_NUMERIC locale is different than LC_CTYPE locale and
+ decimal_point and/or thousands_sep are non-ASCII or longer than
+ 1 byte */
+ setlocale(LC_CTYPE, loc);
+ }
+ }
+
+#define GET_LOCALE_STRING(ATTR) PyUnicode_DecodeLocale(lc->ATTR, NULL)
+#else /* MS_WINDOWS */
+/* Use _W_* fields of Windows strcut lconv */
+#define GET_LOCALE_STRING(ATTR) PyUnicode_FromWideChar(lc->_W_ ## ATTR, -1)
+#endif /* MS_WINDOWS */
+
+ int res = -1;
+
+ *decimal_point = GET_LOCALE_STRING(decimal_point);
+ if (*decimal_point == NULL) {
+ goto done;
+ }
+
+ *thousands_sep = GET_LOCALE_STRING(thousands_sep);
+ if (*thousands_sep == NULL) {
+ goto done;
+ }
+
+ res = 0;
+
+done:
+#ifndef MS_WINDOWS
+ if (loc != NULL) {
+ setlocale(LC_CTYPE, oldloc);
+ }
+ PyMem_Free(oldloc);
+#endif
+ return res;
+
+#undef GET_LOCALE_STRING
+}
diff --git a/contrib/tools/python3/src/Python/formatter_unicode.c b/contrib/tools/python3/src/Python/formatter_unicode.c
new file mode 100644
index 00000000000..e7ec4dd5cb4
--- /dev/null
+++ b/contrib/tools/python3/src/Python/formatter_unicode.c
@@ -0,0 +1,1600 @@
+/* implements the unicode (as opposed to string) version of the
+ built-in formatters for string, int, float. that is, the versions
+ of int.__float__, etc., that take and return unicode objects */
+
+#include "Python.h"
+#include "pycore_fileutils.h"
+#include <locale.h>
+
+/* Raises an exception about an unknown presentation type for this
+ * type. */
+
+static void
+unknown_presentation_type(Py_UCS4 presentation_type,
+ const char* type_name)
+{
+ /* %c might be out-of-range, hence the two cases. */
+ if (presentation_type > 32 && presentation_type < 128)
+ PyErr_Format(PyExc_ValueError,
+ "Unknown format code '%c' "
+ "for object of type '%.200s'",
+ (char)presentation_type,
+ type_name);
+ else
+ PyErr_Format(PyExc_ValueError,
+ "Unknown format code '\\x%x' "
+ "for object of type '%.200s'",
+ (unsigned int)presentation_type,
+ type_name);
+}
+
+static void
+invalid_thousands_separator_type(char specifier, Py_UCS4 presentation_type)
+{
+ assert(specifier == ',' || specifier == '_');
+ if (presentation_type > 32 && presentation_type < 128)
+ PyErr_Format(PyExc_ValueError,
+ "Cannot specify '%c' with '%c'.",
+ specifier, (char)presentation_type);
+ else
+ PyErr_Format(PyExc_ValueError,
+ "Cannot specify '%c' with '\\x%x'.",
+ specifier, (unsigned int)presentation_type);
+}
+
+static void
+invalid_comma_and_underscore(void)
+{
+ PyErr_Format(PyExc_ValueError, "Cannot specify both ',' and '_'.");
+}
+
+/*
+ get_integer consumes 0 or more decimal digit characters from an
+ input string, updates *result with the corresponding positive
+ integer, and returns the number of digits consumed.
+
+ returns -1 on error.
+*/
+static int
+get_integer(PyObject *str, Py_ssize_t *ppos, Py_ssize_t end,
+ Py_ssize_t *result)
+{
+ Py_ssize_t accumulator, digitval, pos = *ppos;
+ int numdigits;
+ int kind = PyUnicode_KIND(str);
+ const void *data = PyUnicode_DATA(str);
+
+ accumulator = numdigits = 0;
+ for (; pos < end; pos++, numdigits++) {
+ digitval = Py_UNICODE_TODECIMAL(PyUnicode_READ(kind, data, pos));
+ if (digitval < 0)
+ break;
+ /*
+ Detect possible overflow before it happens:
+
+ accumulator * 10 + digitval > PY_SSIZE_T_MAX if and only if
+ accumulator > (PY_SSIZE_T_MAX - digitval) / 10.
+ */
+ if (accumulator > (PY_SSIZE_T_MAX - digitval) / 10) {
+ PyErr_Format(PyExc_ValueError,
+ "Too many decimal digits in format string");
+ *ppos = pos;
+ return -1;
+ }
+ accumulator = accumulator * 10 + digitval;
+ }
+ *ppos = pos;
+ *result = accumulator;
+ return numdigits;
+}
+
+/************************************************************************/
+/*********** standard format specifier parsing **************************/
+/************************************************************************/
+
+/* returns true if this character is a specifier alignment token */
+Py_LOCAL_INLINE(int)
+is_alignment_token(Py_UCS4 c)
+{
+ switch (c) {
+ case '<': case '>': case '=': case '^':
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/* returns true if this character is a sign element */
+Py_LOCAL_INLINE(int)
+is_sign_element(Py_UCS4 c)
+{
+ switch (c) {
+ case ' ': case '+': case '-':
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/* Locale type codes. LT_NO_LOCALE must be zero. */
+enum LocaleType {
+ LT_NO_LOCALE = 0,
+ LT_DEFAULT_LOCALE = ',',
+ LT_UNDERSCORE_LOCALE = '_',
+ LT_UNDER_FOUR_LOCALE,
+ LT_CURRENT_LOCALE
+};
+
+typedef struct {
+ Py_UCS4 fill_char;
+ Py_UCS4 align;
+ int alternate;
+ Py_UCS4 sign;
+ Py_ssize_t width;
+ enum LocaleType thousands_separators;
+ Py_ssize_t precision;
+ Py_UCS4 type;
+} InternalFormatSpec;
+
+#if 0
+/* Occasionally useful for debugging. Should normally be commented out. */
+static void
+DEBUG_PRINT_FORMAT_SPEC(InternalFormatSpec *format)
+{
+ printf("internal format spec: fill_char %d\n", format->fill_char);
+ printf("internal format spec: align %d\n", format->align);
+ printf("internal format spec: alternate %d\n", format->alternate);
+ printf("internal format spec: sign %d\n", format->sign);
+ printf("internal format spec: width %zd\n", format->width);
+ printf("internal format spec: thousands_separators %d\n",
+ format->thousands_separators);
+ printf("internal format spec: precision %zd\n", format->precision);
+ printf("internal format spec: type %c\n", format->type);
+ printf("\n");
+}
+#endif
+
+
+/*
+ ptr points to the start of the format_spec, end points just past its end.
+ fills in format with the parsed information.
+ returns 1 on success, 0 on failure.
+ if failure, sets the exception
+*/
+static int
+parse_internal_render_format_spec(PyObject *format_spec,
+ Py_ssize_t start, Py_ssize_t end,
+ InternalFormatSpec *format,
+ char default_type,
+ char default_align)
+{
+ Py_ssize_t pos = start;
+ int kind = PyUnicode_KIND(format_spec);
+ const void *data = PyUnicode_DATA(format_spec);
+ /* end-pos is used throughout this code to specify the length of
+ the input string */
+#define READ_spec(index) PyUnicode_READ(kind, data, index)
+
+ Py_ssize_t consumed;
+ int align_specified = 0;
+ int fill_char_specified = 0;
+
+ format->fill_char = ' ';
+ format->align = default_align;
+ format->alternate = 0;
+ format->sign = '\0';
+ format->width = -1;
+ format->thousands_separators = LT_NO_LOCALE;
+ format->precision = -1;
+ format->type = default_type;
+
+ /* If the second char is an alignment token,
+ then parse the fill char */
+ if (end-pos >= 2 && is_alignment_token(READ_spec(pos+1))) {
+ format->align = READ_spec(pos+1);
+ format->fill_char = READ_spec(pos);
+ fill_char_specified = 1;
+ align_specified = 1;
+ pos += 2;
+ }
+ else if (end-pos >= 1 && is_alignment_token(READ_spec(pos))) {
+ format->align = READ_spec(pos);
+ align_specified = 1;
+ ++pos;
+ }
+
+ /* Parse the various sign options */
+ if (end-pos >= 1 && is_sign_element(READ_spec(pos))) {
+ format->sign = READ_spec(pos);
+ ++pos;
+ }
+
+ /* If the next character is #, we're in alternate mode. This only
+ applies to integers. */
+ if (end-pos >= 1 && READ_spec(pos) == '#') {
+ format->alternate = 1;
+ ++pos;
+ }
+
+ /* The special case for 0-padding (backwards compat) */
+ if (!fill_char_specified && end-pos >= 1 && READ_spec(pos) == '0') {
+ format->fill_char = '0';
+ if (!align_specified) {
+ format->align = '=';
+ }
+ ++pos;
+ }
+
+ consumed = get_integer(format_spec, &pos, end, &format->width);
+ if (consumed == -1)
+ /* Overflow error. Exception already set. */
+ return 0;
+
+ /* If consumed is 0, we didn't consume any characters for the
+ width. In that case, reset the width to -1, because
+ get_integer() will have set it to zero. -1 is how we record
+ that the width wasn't specified. */
+ if (consumed == 0)
+ format->width = -1;
+
+ /* Comma signifies add thousands separators */
+ if (end-pos && READ_spec(pos) == ',') {
+ format->thousands_separators = LT_DEFAULT_LOCALE;
+ ++pos;
+ }
+ /* Underscore signifies add thousands separators */
+ if (end-pos && READ_spec(pos) == '_') {
+ if (format->thousands_separators != LT_NO_LOCALE) {
+ invalid_comma_and_underscore();
+ return 0;
+ }
+ format->thousands_separators = LT_UNDERSCORE_LOCALE;
+ ++pos;
+ }
+ if (end-pos && READ_spec(pos) == ',') {
+ if (format->thousands_separators == LT_UNDERSCORE_LOCALE) {
+ invalid_comma_and_underscore();
+ return 0;
+ }
+ }
+
+ /* Parse field precision */
+ if (end-pos && READ_spec(pos) == '.') {
+ ++pos;
+
+ consumed = get_integer(format_spec, &pos, end, &format->precision);
+ if (consumed == -1)
+ /* Overflow error. Exception already set. */
+ return 0;
+
+ /* Not having a precision after a dot is an error. */
+ if (consumed == 0) {
+ PyErr_Format(PyExc_ValueError,
+ "Format specifier missing precision");
+ return 0;
+ }
+
+ }
+
+ /* Finally, parse the type field. */
+
+ if (end-pos > 1) {
+ /* More than one char remain, invalid format specifier. */
+ PyErr_Format(PyExc_ValueError, "Invalid format specifier");
+ return 0;
+ }
+
+ if (end-pos == 1) {
+ format->type = READ_spec(pos);
+ ++pos;
+ }
+
+ /* Do as much validating as we can, just by looking at the format
+ specifier. Do not take into account what type of formatting
+ we're doing (int, float, string). */
+
+ if (format->thousands_separators) {
+ switch (format->type) {
+ case 'd':
+ case 'e':
+ case 'f':
+ case 'g':
+ case 'E':
+ case 'G':
+ case '%':
+ case 'F':
+ case '\0':
+ /* These are allowed. See PEP 378.*/
+ break;
+ case 'b':
+ case 'o':
+ case 'x':
+ case 'X':
+ /* Underscores are allowed in bin/oct/hex. See PEP 515. */
+ if (format->thousands_separators == LT_UNDERSCORE_LOCALE) {
+ /* Every four digits, not every three, in bin/oct/hex. */
+ format->thousands_separators = LT_UNDER_FOUR_LOCALE;
+ break;
+ }
+ /* fall through */
+ default:
+ invalid_thousands_separator_type(format->thousands_separators, format->type);
+ return 0;
+ }
+ }
+
+ assert (format->align <= 127);
+ assert (format->sign <= 127);
+ return 1;
+}
+
+/* Calculate the padding needed. */
+static void
+calc_padding(Py_ssize_t nchars, Py_ssize_t width, Py_UCS4 align,
+ Py_ssize_t *n_lpadding, Py_ssize_t *n_rpadding,
+ Py_ssize_t *n_total)
+{
+ if (width >= 0) {
+ if (nchars > width)
+ *n_total = nchars;
+ else
+ *n_total = width;
+ }
+ else {
+ /* not specified, use all of the chars and no more */
+ *n_total = nchars;
+ }
+
+ /* Figure out how much leading space we need, based on the
+ aligning */
+ if (align == '>')
+ *n_lpadding = *n_total - nchars;
+ else if (align == '^')
+ *n_lpadding = (*n_total - nchars) / 2;
+ else if (align == '<' || align == '=')
+ *n_lpadding = 0;
+ else {
+ /* We should never have an unspecified alignment. */
+ Py_UNREACHABLE();
+ }
+
+ *n_rpadding = *n_total - nchars - *n_lpadding;
+}
+
+/* Do the padding, and return a pointer to where the caller-supplied
+ content goes. */
+static int
+fill_padding(_PyUnicodeWriter *writer,
+ Py_ssize_t nchars,
+ Py_UCS4 fill_char, Py_ssize_t n_lpadding,
+ Py_ssize_t n_rpadding)
+{
+ Py_ssize_t pos;
+
+ /* Pad on left. */
+ if (n_lpadding) {
+ pos = writer->pos;
+ _PyUnicode_FastFill(writer->buffer, pos, n_lpadding, fill_char);
+ }
+
+ /* Pad on right. */
+ if (n_rpadding) {
+ pos = writer->pos + nchars + n_lpadding;
+ _PyUnicode_FastFill(writer->buffer, pos, n_rpadding, fill_char);
+ }
+
+ /* Pointer to the user content. */
+ writer->pos += n_lpadding;
+ return 0;
+}
+
+/************************************************************************/
+/*********** common routines for numeric formatting *********************/
+/************************************************************************/
+
+/* Locale info needed for formatting integers and the part of floats
+ before and including the decimal. Note that locales only support
+ 8-bit chars, not unicode. */
+typedef struct {
+ PyObject *decimal_point;
+ PyObject *thousands_sep;
+ const char *grouping;
+ char *grouping_buffer;
+} LocaleInfo;
+
+#define LocaleInfo_STATIC_INIT {0, 0, 0, 0}
+
+/* describes the layout for an integer, see the comment in
+ calc_number_widths() for details */
+typedef struct {
+ Py_ssize_t n_lpadding;
+ Py_ssize_t n_prefix;
+ Py_ssize_t n_spadding;
+ Py_ssize_t n_rpadding;
+ char sign;
+ Py_ssize_t n_sign; /* number of digits needed for sign (0/1) */
+ Py_ssize_t n_grouped_digits; /* Space taken up by the digits, including
+ any grouping chars. */
+ Py_ssize_t n_decimal; /* 0 if only an integer */
+ Py_ssize_t n_remainder; /* Digits in decimal and/or exponent part,
+ excluding the decimal itself, if
+ present. */
+
+ /* These 2 are not the widths of fields, but are needed by
+ STRINGLIB_GROUPING. */
+ Py_ssize_t n_digits; /* The number of digits before a decimal
+ or exponent. */
+ Py_ssize_t n_min_width; /* The min_width we used when we computed
+ the n_grouped_digits width. */
+} NumberFieldWidths;
+
+
+/* Given a number of the form:
+ digits[remainder]
+ where ptr points to the start and end points to the end, find where
+ the integer part ends. This could be a decimal, an exponent, both,
+ or neither.
+ If a decimal point is present, set *has_decimal and increment
+ remainder beyond it.
+ Results are undefined (but shouldn't crash) for improperly
+ formatted strings.
+*/
+static void
+parse_number(PyObject *s, Py_ssize_t pos, Py_ssize_t end,
+ Py_ssize_t *n_remainder, int *has_decimal)
+{
+ Py_ssize_t remainder;
+ int kind = PyUnicode_KIND(s);
+ const void *data = PyUnicode_DATA(s);
+
+ while (pos<end && Py_ISDIGIT(PyUnicode_READ(kind, data, pos)))
+ ++pos;
+ remainder = pos;
+
+ /* Does remainder start with a decimal point? */
+ *has_decimal = pos<end && PyUnicode_READ(kind, data, remainder) == '.';
+
+ /* Skip the decimal point. */
+ if (*has_decimal)
+ remainder++;
+
+ *n_remainder = end - remainder;
+}
+
+/* not all fields of format are used. for example, precision is
+ unused. should this take discrete params in order to be more clear
+ about what it does? or is passing a single format parameter easier
+ and more efficient enough to justify a little obfuscation?
+ Return -1 on error. */
+static Py_ssize_t
+calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix,
+ Py_UCS4 sign_char, Py_ssize_t n_start,
+ Py_ssize_t n_end, Py_ssize_t n_remainder,
+ int has_decimal, const LocaleInfo *locale,
+ const InternalFormatSpec *format, Py_UCS4 *maxchar)
+{
+ Py_ssize_t n_non_digit_non_padding;
+ Py_ssize_t n_padding;
+
+ spec->n_digits = n_end - n_start - n_remainder - (has_decimal?1:0);
+ spec->n_lpadding = 0;
+ spec->n_prefix = n_prefix;
+ spec->n_decimal = has_decimal ? PyUnicode_GET_LENGTH(locale->decimal_point) : 0;
+ spec->n_remainder = n_remainder;
+ spec->n_spadding = 0;
+ spec->n_rpadding = 0;
+ spec->sign = '\0';
+ spec->n_sign = 0;
+
+ /* the output will look like:
+ | |
+ | <lpadding> <sign> <prefix> <spadding> <grouped_digits> <decimal> <remainder> <rpadding> |
+ | |
+
+ sign is computed from format->sign and the actual
+ sign of the number
+
+ prefix is given (it's for the '0x' prefix)
+
+ digits is already known
+
+ the total width is either given, or computed from the
+ actual digits
+
+ only one of lpadding, spadding, and rpadding can be non-zero,
+ and it's calculated from the width and other fields
+ */
+
+ /* compute the various parts we're going to write */
+ switch (format->sign) {
+ case '+':
+ /* always put a + or - */
+ spec->n_sign = 1;
+ spec->sign = (sign_char == '-' ? '-' : '+');
+ break;
+ case ' ':
+ spec->n_sign = 1;
+ spec->sign = (sign_char == '-' ? '-' : ' ');
+ break;
+ default:
+ /* Not specified, or the default (-) */
+ if (sign_char == '-') {
+ spec->n_sign = 1;
+ spec->sign = '-';
+ }
+ }
+
+ /* The number of chars used for non-digits and non-padding. */
+ n_non_digit_non_padding = spec->n_sign + spec->n_prefix + spec->n_decimal +
+ spec->n_remainder;
+
+ /* min_width can go negative, that's okay. format->width == -1 means
+ we don't care. */
+ if (format->fill_char == '0' && format->align == '=')
+ spec->n_min_width = format->width - n_non_digit_non_padding;
+ else
+ spec->n_min_width = 0;
+
+ if (spec->n_digits == 0)
+ /* This case only occurs when using 'c' formatting, we need
+ to special case it because the grouping code always wants
+ to have at least one character. */
+ spec->n_grouped_digits = 0;
+ else {
+ Py_UCS4 grouping_maxchar;
+ spec->n_grouped_digits = _PyUnicode_InsertThousandsGrouping(
+ NULL, 0,
+ NULL, 0, spec->n_digits,
+ spec->n_min_width,
+ locale->grouping, locale->thousands_sep, &grouping_maxchar);
+ if (spec->n_grouped_digits == -1) {
+ return -1;
+ }
+ *maxchar = Py_MAX(*maxchar, grouping_maxchar);
+ }
+
+ /* Given the desired width and the total of digit and non-digit
+ space we consume, see if we need any padding. format->width can
+ be negative (meaning no padding), but this code still works in
+ that case. */
+ n_padding = format->width -
+ (n_non_digit_non_padding + spec->n_grouped_digits);
+ if (n_padding > 0) {
+ /* Some padding is needed. Determine if it's left, space, or right. */
+ switch (format->align) {
+ case '<':
+ spec->n_rpadding = n_padding;
+ break;
+ case '^':
+ spec->n_lpadding = n_padding / 2;
+ spec->n_rpadding = n_padding - spec->n_lpadding;
+ break;
+ case '=':
+ spec->n_spadding = n_padding;
+ break;
+ case '>':
+ spec->n_lpadding = n_padding;
+ break;
+ default:
+ /* Shouldn't get here */
+ Py_UNREACHABLE();
+ }
+ }
+
+ if (spec->n_lpadding || spec->n_spadding || spec->n_rpadding)
+ *maxchar = Py_MAX(*maxchar, format->fill_char);
+
+ if (spec->n_decimal)
+ *maxchar = Py_MAX(*maxchar, PyUnicode_MAX_CHAR_VALUE(locale->decimal_point));
+
+ return spec->n_lpadding + spec->n_sign + spec->n_prefix +
+ spec->n_spadding + spec->n_grouped_digits + spec->n_decimal +
+ spec->n_remainder + spec->n_rpadding;
+}
+
+/* Fill in the digit parts of a number's string representation,
+ as determined in calc_number_widths().
+ Return -1 on error, or 0 on success. */
+static int
+fill_number(_PyUnicodeWriter *writer, const NumberFieldWidths *spec,
+ PyObject *digits, Py_ssize_t d_start,
+ PyObject *prefix, Py_ssize_t p_start,
+ Py_UCS4 fill_char,
+ LocaleInfo *locale, int toupper)
+{
+ /* Used to keep track of digits, decimal, and remainder. */
+ Py_ssize_t d_pos = d_start;
+ const unsigned int kind = writer->kind;
+ const void *data = writer->data;
+ Py_ssize_t r;
+
+ if (spec->n_lpadding) {
+ _PyUnicode_FastFill(writer->buffer,
+ writer->pos, spec->n_lpadding, fill_char);
+ writer->pos += spec->n_lpadding;
+ }
+ if (spec->n_sign == 1) {
+ PyUnicode_WRITE(kind, data, writer->pos, spec->sign);
+ writer->pos++;
+ }
+ if (spec->n_prefix) {
+ _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos,
+ prefix, p_start,
+ spec->n_prefix);
+ if (toupper) {
+ Py_ssize_t t;
+ for (t = 0; t < spec->n_prefix; t++) {
+ Py_UCS4 c = PyUnicode_READ(kind, data, writer->pos + t);
+ c = Py_TOUPPER(c);
+ assert (c <= 127);
+ PyUnicode_WRITE(kind, data, writer->pos + t, c);
+ }
+ }
+ writer->pos += spec->n_prefix;
+ }
+ if (spec->n_spadding) {
+ _PyUnicode_FastFill(writer->buffer,
+ writer->pos, spec->n_spadding, fill_char);
+ writer->pos += spec->n_spadding;
+ }
+
+ /* Only for type 'c' special case, it has no digits. */
+ if (spec->n_digits != 0) {
+ /* Fill the digits with InsertThousandsGrouping. */
+ r = _PyUnicode_InsertThousandsGrouping(
+ writer, spec->n_grouped_digits,
+ digits, d_pos, spec->n_digits,
+ spec->n_min_width,
+ locale->grouping, locale->thousands_sep, NULL);
+ if (r == -1)
+ return -1;
+ assert(r == spec->n_grouped_digits);
+ d_pos += spec->n_digits;
+ }
+ if (toupper) {
+ Py_ssize_t t;
+ for (t = 0; t < spec->n_grouped_digits; t++) {
+ Py_UCS4 c = PyUnicode_READ(kind, data, writer->pos + t);
+ c = Py_TOUPPER(c);
+ if (c > 127) {
+ PyErr_SetString(PyExc_SystemError, "non-ascii grouped digit");
+ return -1;
+ }
+ PyUnicode_WRITE(kind, data, writer->pos + t, c);
+ }
+ }
+ writer->pos += spec->n_grouped_digits;
+
+ if (spec->n_decimal) {
+ _PyUnicode_FastCopyCharacters(
+ writer->buffer, writer->pos,
+ locale->decimal_point, 0, spec->n_decimal);
+ writer->pos += spec->n_decimal;
+ d_pos += 1;
+ }
+
+ if (spec->n_remainder) {
+ _PyUnicode_FastCopyCharacters(
+ writer->buffer, writer->pos,
+ digits, d_pos, spec->n_remainder);
+ writer->pos += spec->n_remainder;
+ /* d_pos += spec->n_remainder; */
+ }
+
+ if (spec->n_rpadding) {
+ _PyUnicode_FastFill(writer->buffer,
+ writer->pos, spec->n_rpadding,
+ fill_char);
+ writer->pos += spec->n_rpadding;
+ }
+ return 0;
+}
+
+static const char no_grouping[1] = {CHAR_MAX};
+
+/* Find the decimal point character(s?), thousands_separator(s?), and
+ grouping description, either for the current locale if type is
+ LT_CURRENT_LOCALE, a hard-coded locale if LT_DEFAULT_LOCALE or
+ LT_UNDERSCORE_LOCALE/LT_UNDER_FOUR_LOCALE, or none if LT_NO_LOCALE. */
+static int
+get_locale_info(enum LocaleType type, LocaleInfo *locale_info)
+{
+ switch (type) {
+ case LT_CURRENT_LOCALE: {
+ struct lconv *lc = localeconv();
+ if (_Py_GetLocaleconvNumeric(lc,
+ &locale_info->decimal_point,
+ &locale_info->thousands_sep) < 0) {
+ return -1;
+ }
+
+ /* localeconv() grouping can become a dangling pointer or point
+ to a different string if another thread calls localeconv() during
+ the string formatting. Copy the string to avoid this risk. */
+ locale_info->grouping_buffer = _PyMem_Strdup(lc->grouping);
+ if (locale_info->grouping_buffer == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ locale_info->grouping = locale_info->grouping_buffer;
+ break;
+ }
+ case LT_DEFAULT_LOCALE:
+ case LT_UNDERSCORE_LOCALE:
+ case LT_UNDER_FOUR_LOCALE:
+ locale_info->decimal_point = PyUnicode_FromOrdinal('.');
+ locale_info->thousands_sep = PyUnicode_FromOrdinal(
+ type == LT_DEFAULT_LOCALE ? ',' : '_');
+ if (!locale_info->decimal_point || !locale_info->thousands_sep)
+ return -1;
+ if (type != LT_UNDER_FOUR_LOCALE)
+ locale_info->grouping = "\3"; /* Group every 3 characters. The
+ (implicit) trailing 0 means repeat
+ infinitely. */
+ else
+ locale_info->grouping = "\4"; /* Bin/oct/hex group every four. */
+ break;
+ case LT_NO_LOCALE:
+ locale_info->decimal_point = PyUnicode_FromOrdinal('.');
+ locale_info->thousands_sep = PyUnicode_New(0, 0);
+ if (!locale_info->decimal_point || !locale_info->thousands_sep)
+ return -1;
+ locale_info->grouping = no_grouping;
+ break;
+ }
+ return 0;
+}
+
+static void
+free_locale_info(LocaleInfo *locale_info)
+{
+ Py_XDECREF(locale_info->decimal_point);
+ Py_XDECREF(locale_info->thousands_sep);
+ PyMem_Free(locale_info->grouping_buffer);
+}
+
+/************************************************************************/
+/*********** string formatting ******************************************/
+/************************************************************************/
+
+static int
+format_string_internal(PyObject *value, const InternalFormatSpec *format,
+ _PyUnicodeWriter *writer)
+{
+ Py_ssize_t lpad;
+ Py_ssize_t rpad;
+ Py_ssize_t total;
+ Py_ssize_t len;
+ int result = -1;
+ Py_UCS4 maxchar;
+
+ assert(PyUnicode_IS_READY(value));
+ len = PyUnicode_GET_LENGTH(value);
+
+ /* sign is not allowed on strings */
+ if (format->sign != '\0') {
+ if (format->sign == ' ') {
+ PyErr_SetString(PyExc_ValueError,
+ "Space not allowed in string format specifier");
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "Sign not allowed in string format specifier");
+ }
+ goto done;
+ }
+
+ /* alternate is not allowed on strings */
+ if (format->alternate) {
+ PyErr_SetString(PyExc_ValueError,
+ "Alternate form (#) not allowed in string format "
+ "specifier");
+ goto done;
+ }
+
+ /* '=' alignment not allowed on strings */
+ if (format->align == '=') {
+ PyErr_SetString(PyExc_ValueError,
+ "'=' alignment not allowed "
+ "in string format specifier");
+ goto done;
+ }
+
+ if ((format->width == -1 || format->width <= len)
+ && (format->precision == -1 || format->precision >= len)) {
+ /* Fast path */
+ return _PyUnicodeWriter_WriteStr(writer, value);
+ }
+
+ /* if precision is specified, output no more that format.precision
+ characters */
+ if (format->precision >= 0 && len >= format->precision) {
+ len = format->precision;
+ }
+
+ calc_padding(len, format->width, format->align, &lpad, &rpad, &total);
+
+ maxchar = writer->maxchar;
+ if (lpad != 0 || rpad != 0)
+ maxchar = Py_MAX(maxchar, format->fill_char);
+ if (PyUnicode_MAX_CHAR_VALUE(value) > maxchar) {
+ Py_UCS4 valmaxchar = _PyUnicode_FindMaxChar(value, 0, len);
+ maxchar = Py_MAX(maxchar, valmaxchar);
+ }
+
+ /* allocate the resulting string */
+ if (_PyUnicodeWriter_Prepare(writer, total, maxchar) == -1)
+ goto done;
+
+ /* Write into that space. First the padding. */
+ result = fill_padding(writer, len, format->fill_char, lpad, rpad);
+ if (result == -1)
+ goto done;
+
+ /* Then the source string. */
+ if (len) {
+ _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos,
+ value, 0, len);
+ }
+ writer->pos += (len + rpad);
+ result = 0;
+
+done:
+ return result;
+}
+
+
+/************************************************************************/
+/*********** long formatting ********************************************/
+/************************************************************************/
+
+static int
+format_long_internal(PyObject *value, const InternalFormatSpec *format,
+ _PyUnicodeWriter *writer)
+{
+ int result = -1;
+ Py_UCS4 maxchar = 127;
+ PyObject *tmp = NULL;
+ Py_ssize_t inumeric_chars;
+ Py_UCS4 sign_char = '\0';
+ Py_ssize_t n_digits; /* count of digits need from the computed
+ string */
+ Py_ssize_t n_remainder = 0; /* Used only for 'c' formatting, which
+ produces non-digits */
+ Py_ssize_t n_prefix = 0; /* Count of prefix chars, (e.g., '0x') */
+ Py_ssize_t n_total;
+ Py_ssize_t prefix = 0;
+ NumberFieldWidths spec;
+ long x;
+
+ /* Locale settings, either from the actual locale or
+ from a hard-code pseudo-locale */
+ LocaleInfo locale = LocaleInfo_STATIC_INIT;
+
+ /* no precision allowed on integers */
+ if (format->precision != -1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Precision not allowed in integer format specifier");
+ goto done;
+ }
+
+ /* special case for character formatting */
+ if (format->type == 'c') {
+ /* error to specify a sign */
+ if (format->sign != '\0') {
+ PyErr_SetString(PyExc_ValueError,
+ "Sign not allowed with integer"
+ " format specifier 'c'");
+ goto done;
+ }
+ /* error to request alternate format */
+ if (format->alternate) {
+ PyErr_SetString(PyExc_ValueError,
+ "Alternate form (#) not allowed with integer"
+ " format specifier 'c'");
+ goto done;
+ }
+
+ /* taken from unicodeobject.c formatchar() */
+ /* Integer input truncated to a character */
+ x = PyLong_AsLong(value);
+ if (x == -1 && PyErr_Occurred())
+ goto done;
+ if (x < 0 || x > 0x10ffff) {
+ PyErr_SetString(PyExc_OverflowError,
+ "%c arg not in range(0x110000)");
+ goto done;
+ }
+ tmp = PyUnicode_FromOrdinal(x);
+ inumeric_chars = 0;
+ n_digits = 1;
+ maxchar = Py_MAX(maxchar, (Py_UCS4)x);
+
+ /* As a sort-of hack, we tell calc_number_widths that we only
+ have "remainder" characters. calc_number_widths thinks
+ these are characters that don't get formatted, only copied
+ into the output string. We do this for 'c' formatting,
+ because the characters are likely to be non-digits. */
+ n_remainder = 1;
+ }
+ else {
+ int base;
+ int leading_chars_to_skip = 0; /* Number of characters added by
+ PyNumber_ToBase that we want to
+ skip over. */
+
+ /* Compute the base and how many characters will be added by
+ PyNumber_ToBase */
+ switch (format->type) {
+ case 'b':
+ base = 2;
+ leading_chars_to_skip = 2; /* 0b */
+ break;
+ case 'o':
+ base = 8;
+ leading_chars_to_skip = 2; /* 0o */
+ break;
+ case 'x':
+ case 'X':
+ base = 16;
+ leading_chars_to_skip = 2; /* 0x */
+ break;
+ default: /* shouldn't be needed, but stops a compiler warning */
+ case 'd':
+ case 'n':
+ base = 10;
+ break;
+ }
+
+ if (format->sign != '+' && format->sign != ' '
+ && format->width == -1
+ && format->type != 'X' && format->type != 'n'
+ && !format->thousands_separators
+ && PyLong_CheckExact(value))
+ {
+ /* Fast path */
+ return _PyLong_FormatWriter(writer, value, base, format->alternate);
+ }
+
+ /* The number of prefix chars is the same as the leading
+ chars to skip */
+ if (format->alternate)
+ n_prefix = leading_chars_to_skip;
+
+ /* Do the hard part, converting to a string in a given base */
+ tmp = _PyLong_Format(value, base);
+ if (tmp == NULL || PyUnicode_READY(tmp) == -1)
+ goto done;
+
+ inumeric_chars = 0;
+ n_digits = PyUnicode_GET_LENGTH(tmp);
+
+ prefix = inumeric_chars;
+
+ /* Is a sign character present in the output? If so, remember it
+ and skip it */
+ if (PyUnicode_READ_CHAR(tmp, inumeric_chars) == '-') {
+ sign_char = '-';
+ ++prefix;
+ ++leading_chars_to_skip;
+ }
+
+ /* Skip over the leading chars (0x, 0b, etc.) */
+ n_digits -= leading_chars_to_skip;
+ inumeric_chars += leading_chars_to_skip;
+ }
+
+ /* Determine the grouping, separator, and decimal point, if any. */
+ if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
+ format->thousands_separators,
+ &locale) == -1)
+ goto done;
+
+ /* Calculate how much memory we'll need. */
+ n_total = calc_number_widths(&spec, n_prefix, sign_char, inumeric_chars,
+ inumeric_chars + n_digits, n_remainder, 0,
+ &locale, format, &maxchar);
+ if (n_total == -1) {
+ goto done;
+ }
+
+ /* Allocate the memory. */
+ if (_PyUnicodeWriter_Prepare(writer, n_total, maxchar) == -1)
+ goto done;
+
+ /* Populate the memory. */
+ result = fill_number(writer, &spec,
+ tmp, inumeric_chars,
+ tmp, prefix, format->fill_char,
+ &locale, format->type == 'X');
+
+done:
+ Py_XDECREF(tmp);
+ free_locale_info(&locale);
+ return result;
+}
+
+/************************************************************************/
+/*********** float formatting *******************************************/
+/************************************************************************/
+
+/* much of this is taken from unicodeobject.c */
+static int
+format_float_internal(PyObject *value,
+ const InternalFormatSpec *format,
+ _PyUnicodeWriter *writer)
+{
+ char *buf = NULL; /* buffer returned from PyOS_double_to_string */
+ Py_ssize_t n_digits;
+ Py_ssize_t n_remainder;
+ Py_ssize_t n_total;
+ int has_decimal;
+ double val;
+ int precision, default_precision = 6;
+ Py_UCS4 type = format->type;
+ int add_pct = 0;
+ Py_ssize_t index;
+ NumberFieldWidths spec;
+ int flags = 0;
+ int result = -1;
+ Py_UCS4 maxchar = 127;
+ Py_UCS4 sign_char = '\0';
+ int float_type; /* Used to see if we have a nan, inf, or regular float. */
+ PyObject *unicode_tmp = NULL;
+
+ /* Locale settings, either from the actual locale or
+ from a hard-code pseudo-locale */
+ LocaleInfo locale = LocaleInfo_STATIC_INIT;
+
+ if (format->precision > INT_MAX) {
+ PyErr_SetString(PyExc_ValueError, "precision too big");
+ goto done;
+ }
+ precision = (int)format->precision;
+
+ if (format->alternate)
+ flags |= Py_DTSF_ALT;
+
+ if (type == '\0') {
+ /* Omitted type specifier. Behaves in the same way as repr(x)
+ and str(x) if no precision is given, else like 'g', but with
+ at least one digit after the decimal point. */
+ flags |= Py_DTSF_ADD_DOT_0;
+ type = 'r';
+ default_precision = 0;
+ }
+
+ if (type == 'n')
+ /* 'n' is the same as 'g', except for the locale used to
+ format the result. We take care of that later. */
+ type = 'g';
+
+ val = PyFloat_AsDouble(value);
+ if (val == -1.0 && PyErr_Occurred())
+ goto done;
+
+ if (type == '%') {
+ type = 'f';
+ val *= 100;
+ add_pct = 1;
+ }
+
+ if (precision < 0)
+ precision = default_precision;
+ else if (type == 'r')
+ type = 'g';
+
+ /* Cast "type", because if we're in unicode we need to pass an
+ 8-bit char. This is safe, because we've restricted what "type"
+ can be. */
+ buf = PyOS_double_to_string(val, (char)type, precision, flags,
+ &float_type);
+ if (buf == NULL)
+ goto done;
+ n_digits = strlen(buf);
+
+ if (add_pct) {
+ /* We know that buf has a trailing zero (since we just called
+ strlen() on it), and we don't use that fact any more. So we
+ can just write over the trailing zero. */
+ buf[n_digits] = '%';
+ n_digits += 1;
+ }
+
+ if (format->sign != '+' && format->sign != ' '
+ && format->width == -1
+ && format->type != 'n'
+ && !format->thousands_separators)
+ {
+ /* Fast path */
+ result = _PyUnicodeWriter_WriteASCIIString(writer, buf, n_digits);
+ PyMem_Free(buf);
+ return result;
+ }
+
+ /* Since there is no unicode version of PyOS_double_to_string,
+ just use the 8 bit version and then convert to unicode. */
+ unicode_tmp = _PyUnicode_FromASCII(buf, n_digits);
+ PyMem_Free(buf);
+ if (unicode_tmp == NULL)
+ goto done;
+
+ /* Is a sign character present in the output? If so, remember it
+ and skip it */
+ index = 0;
+ if (PyUnicode_READ_CHAR(unicode_tmp, index) == '-') {
+ sign_char = '-';
+ ++index;
+ --n_digits;
+ }
+
+ /* Determine if we have any "remainder" (after the digits, might include
+ decimal or exponent or both (or neither)) */
+ parse_number(unicode_tmp, index, index + n_digits, &n_remainder, &has_decimal);
+
+ /* Determine the grouping, separator, and decimal point, if any. */
+ if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
+ format->thousands_separators,
+ &locale) == -1)
+ goto done;
+
+ /* Calculate how much memory we'll need. */
+ n_total = calc_number_widths(&spec, 0, sign_char, index,
+ index + n_digits, n_remainder, has_decimal,
+ &locale, format, &maxchar);
+ if (n_total == -1) {
+ goto done;
+ }
+
+ /* Allocate the memory. */
+ if (_PyUnicodeWriter_Prepare(writer, n_total, maxchar) == -1)
+ goto done;
+
+ /* Populate the memory. */
+ result = fill_number(writer, &spec,
+ unicode_tmp, index,
+ NULL, 0, format->fill_char,
+ &locale, 0);
+
+done:
+ Py_XDECREF(unicode_tmp);
+ free_locale_info(&locale);
+ return result;
+}
+
+/************************************************************************/
+/*********** complex formatting *****************************************/
+/************************************************************************/
+
+static int
+format_complex_internal(PyObject *value,
+ const InternalFormatSpec *format,
+ _PyUnicodeWriter *writer)
+{
+ double re;
+ double im;
+ char *re_buf = NULL; /* buffer returned from PyOS_double_to_string */
+ char *im_buf = NULL; /* buffer returned from PyOS_double_to_string */
+
+ InternalFormatSpec tmp_format = *format;
+ Py_ssize_t n_re_digits;
+ Py_ssize_t n_im_digits;
+ Py_ssize_t n_re_remainder;
+ Py_ssize_t n_im_remainder;
+ Py_ssize_t n_re_total;
+ Py_ssize_t n_im_total;
+ int re_has_decimal;
+ int im_has_decimal;
+ int precision, default_precision = 6;
+ Py_UCS4 type = format->type;
+ Py_ssize_t i_re;
+ Py_ssize_t i_im;
+ NumberFieldWidths re_spec;
+ NumberFieldWidths im_spec;
+ int flags = 0;
+ int result = -1;
+ Py_UCS4 maxchar = 127;
+ enum PyUnicode_Kind rkind;
+ void *rdata;
+ Py_UCS4 re_sign_char = '\0';
+ Py_UCS4 im_sign_char = '\0';
+ int re_float_type; /* Used to see if we have a nan, inf, or regular float. */
+ int im_float_type;
+ int add_parens = 0;
+ int skip_re = 0;
+ Py_ssize_t lpad;
+ Py_ssize_t rpad;
+ Py_ssize_t total;
+ PyObject *re_unicode_tmp = NULL;
+ PyObject *im_unicode_tmp = NULL;
+
+ /* Locale settings, either from the actual locale or
+ from a hard-code pseudo-locale */
+ LocaleInfo locale = LocaleInfo_STATIC_INIT;
+
+ if (format->precision > INT_MAX) {
+ PyErr_SetString(PyExc_ValueError, "precision too big");
+ goto done;
+ }
+ precision = (int)format->precision;
+
+ /* Zero padding is not allowed. */
+ if (format->fill_char == '0') {
+ PyErr_SetString(PyExc_ValueError,
+ "Zero padding is not allowed in complex format "
+ "specifier");
+ goto done;
+ }
+
+ /* Neither is '=' alignment . */
+ if (format->align == '=') {
+ PyErr_SetString(PyExc_ValueError,
+ "'=' alignment flag is not allowed in complex format "
+ "specifier");
+ goto done;
+ }
+
+ re = PyComplex_RealAsDouble(value);
+ if (re == -1.0 && PyErr_Occurred())
+ goto done;
+ im = PyComplex_ImagAsDouble(value);
+ if (im == -1.0 && PyErr_Occurred())
+ goto done;
+
+ if (format->alternate)
+ flags |= Py_DTSF_ALT;
+
+ if (type == '\0') {
+ /* Omitted type specifier. Should be like str(self). */
+ type = 'r';
+ default_precision = 0;
+ if (re == 0.0 && copysign(1.0, re) == 1.0)
+ skip_re = 1;
+ else
+ add_parens = 1;
+ }
+
+ if (type == 'n')
+ /* 'n' is the same as 'g', except for the locale used to
+ format the result. We take care of that later. */
+ type = 'g';
+
+ if (precision < 0)
+ precision = default_precision;
+ else if (type == 'r')
+ type = 'g';
+
+ /* Cast "type", because if we're in unicode we need to pass an
+ 8-bit char. This is safe, because we've restricted what "type"
+ can be. */
+ re_buf = PyOS_double_to_string(re, (char)type, precision, flags,
+ &re_float_type);
+ if (re_buf == NULL)
+ goto done;
+ im_buf = PyOS_double_to_string(im, (char)type, precision, flags,
+ &im_float_type);
+ if (im_buf == NULL)
+ goto done;
+
+ n_re_digits = strlen(re_buf);
+ n_im_digits = strlen(im_buf);
+
+ /* Since there is no unicode version of PyOS_double_to_string,
+ just use the 8 bit version and then convert to unicode. */
+ re_unicode_tmp = _PyUnicode_FromASCII(re_buf, n_re_digits);
+ if (re_unicode_tmp == NULL)
+ goto done;
+ i_re = 0;
+
+ im_unicode_tmp = _PyUnicode_FromASCII(im_buf, n_im_digits);
+ if (im_unicode_tmp == NULL)
+ goto done;
+ i_im = 0;
+
+ /* Is a sign character present in the output? If so, remember it
+ and skip it */
+ if (PyUnicode_READ_CHAR(re_unicode_tmp, i_re) == '-') {
+ re_sign_char = '-';
+ ++i_re;
+ --n_re_digits;
+ }
+ if (PyUnicode_READ_CHAR(im_unicode_tmp, i_im) == '-') {
+ im_sign_char = '-';
+ ++i_im;
+ --n_im_digits;
+ }
+
+ /* Determine if we have any "remainder" (after the digits, might include
+ decimal or exponent or both (or neither)) */
+ parse_number(re_unicode_tmp, i_re, i_re + n_re_digits,
+ &n_re_remainder, &re_has_decimal);
+ parse_number(im_unicode_tmp, i_im, i_im + n_im_digits,
+ &n_im_remainder, &im_has_decimal);
+
+ /* Determine the grouping, separator, and decimal point, if any. */
+ if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
+ format->thousands_separators,
+ &locale) == -1)
+ goto done;
+
+ /* Turn off any padding. We'll do it later after we've composed
+ the numbers without padding. */
+ tmp_format.fill_char = '\0';
+ tmp_format.align = '<';
+ tmp_format.width = -1;
+
+ /* Calculate how much memory we'll need. */
+ n_re_total = calc_number_widths(&re_spec, 0, re_sign_char,
+ i_re, i_re + n_re_digits, n_re_remainder,
+ re_has_decimal, &locale, &tmp_format,
+ &maxchar);
+ if (n_re_total == -1) {
+ goto done;
+ }
+
+ /* Same formatting, but always include a sign, unless the real part is
+ * going to be omitted, in which case we use whatever sign convention was
+ * requested by the original format. */
+ if (!skip_re)
+ tmp_format.sign = '+';
+ n_im_total = calc_number_widths(&im_spec, 0, im_sign_char,
+ i_im, i_im + n_im_digits, n_im_remainder,
+ im_has_decimal, &locale, &tmp_format,
+ &maxchar);
+ if (n_im_total == -1) {
+ goto done;
+ }
+
+ if (skip_re)
+ n_re_total = 0;
+
+ /* Add 1 for the 'j', and optionally 2 for parens. */
+ calc_padding(n_re_total + n_im_total + 1 + add_parens * 2,
+ format->width, format->align, &lpad, &rpad, &total);
+
+ if (lpad || rpad)
+ maxchar = Py_MAX(maxchar, format->fill_char);
+
+ if (_PyUnicodeWriter_Prepare(writer, total, maxchar) == -1)
+ goto done;
+ rkind = writer->kind;
+ rdata = writer->data;
+
+ /* Populate the memory. First, the padding. */
+ result = fill_padding(writer,
+ n_re_total + n_im_total + 1 + add_parens * 2,
+ format->fill_char, lpad, rpad);
+ if (result == -1)
+ goto done;
+
+ if (add_parens) {
+ PyUnicode_WRITE(rkind, rdata, writer->pos, '(');
+ writer->pos++;
+ }
+
+ if (!skip_re) {
+ result = fill_number(writer, &re_spec,
+ re_unicode_tmp, i_re,
+ NULL, 0,
+ 0,
+ &locale, 0);
+ if (result == -1)
+ goto done;
+ }
+ result = fill_number(writer, &im_spec,
+ im_unicode_tmp, i_im,
+ NULL, 0,
+ 0,
+ &locale, 0);
+ if (result == -1)
+ goto done;
+ PyUnicode_WRITE(rkind, rdata, writer->pos, 'j');
+ writer->pos++;
+
+ if (add_parens) {
+ PyUnicode_WRITE(rkind, rdata, writer->pos, ')');
+ writer->pos++;
+ }
+
+ writer->pos += rpad;
+
+done:
+ PyMem_Free(re_buf);
+ PyMem_Free(im_buf);
+ Py_XDECREF(re_unicode_tmp);
+ Py_XDECREF(im_unicode_tmp);
+ free_locale_info(&locale);
+ return result;
+}
+
+/************************************************************************/
+/*********** built in formatters ****************************************/
+/************************************************************************/
+static int
+format_obj(PyObject *obj, _PyUnicodeWriter *writer)
+{
+ PyObject *str;
+ int err;
+
+ str = PyObject_Str(obj);
+ if (str == NULL)
+ return -1;
+ err = _PyUnicodeWriter_WriteStr(writer, str);
+ Py_DECREF(str);
+ return err;
+}
+
+int
+_PyUnicode_FormatAdvancedWriter(_PyUnicodeWriter *writer,
+ PyObject *obj,
+ PyObject *format_spec,
+ Py_ssize_t start, Py_ssize_t end)
+{
+ InternalFormatSpec format;
+
+ assert(PyUnicode_Check(obj));
+
+ /* check for the special case of zero length format spec, make
+ it equivalent to str(obj) */
+ if (start == end) {
+ if (PyUnicode_CheckExact(obj))
+ return _PyUnicodeWriter_WriteStr(writer, obj);
+ else
+ return format_obj(obj, writer);
+ }
+
+ /* parse the format_spec */
+ if (!parse_internal_render_format_spec(format_spec, start, end,
+ &format, 's', '<'))
+ return -1;
+
+ /* type conversion? */
+ switch (format.type) {
+ case 's':
+ /* no type conversion needed, already a string. do the formatting */
+ return format_string_internal(obj, &format, writer);
+ default:
+ /* unknown */
+ unknown_presentation_type(format.type, Py_TYPE(obj)->tp_name);
+ return -1;
+ }
+}
+
+int
+_PyLong_FormatAdvancedWriter(_PyUnicodeWriter *writer,
+ PyObject *obj,
+ PyObject *format_spec,
+ Py_ssize_t start, Py_ssize_t end)
+{
+ PyObject *tmp = NULL;
+ InternalFormatSpec format;
+ int result = -1;
+
+ /* check for the special case of zero length format spec, make
+ it equivalent to str(obj) */
+ if (start == end) {
+ if (PyLong_CheckExact(obj))
+ return _PyLong_FormatWriter(writer, obj, 10, 0);
+ else
+ return format_obj(obj, writer);
+ }
+
+ /* parse the format_spec */
+ if (!parse_internal_render_format_spec(format_spec, start, end,
+ &format, 'd', '>'))
+ goto done;
+
+ /* type conversion? */
+ switch (format.type) {
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'o':
+ case 'x':
+ case 'X':
+ case 'n':
+ /* no type conversion needed, already an int. do the formatting */
+ result = format_long_internal(obj, &format, writer);
+ break;
+
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ case 'g':
+ case 'G':
+ case '%':
+ /* convert to float */
+ tmp = PyNumber_Float(obj);
+ if (tmp == NULL)
+ goto done;
+ result = format_float_internal(tmp, &format, writer);
+ break;
+
+ default:
+ /* unknown */
+ unknown_presentation_type(format.type, Py_TYPE(obj)->tp_name);
+ goto done;
+ }
+
+done:
+ Py_XDECREF(tmp);
+ return result;
+}
+
+int
+_PyFloat_FormatAdvancedWriter(_PyUnicodeWriter *writer,
+ PyObject *obj,
+ PyObject *format_spec,
+ Py_ssize_t start, Py_ssize_t end)
+{
+ InternalFormatSpec format;
+
+ /* check for the special case of zero length format spec, make
+ it equivalent to str(obj) */
+ if (start == end)
+ return format_obj(obj, writer);
+
+ /* parse the format_spec */
+ if (!parse_internal_render_format_spec(format_spec, start, end,
+ &format, '\0', '>'))
+ return -1;
+
+ /* type conversion? */
+ switch (format.type) {
+ case '\0': /* No format code: like 'g', but with at least one decimal. */
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ case 'g':
+ case 'G':
+ case 'n':
+ case '%':
+ /* no conversion, already a float. do the formatting */
+ return format_float_internal(obj, &format, writer);
+
+ default:
+ /* unknown */
+ unknown_presentation_type(format.type, Py_TYPE(obj)->tp_name);
+ return -1;
+ }
+}
+
+int
+_PyComplex_FormatAdvancedWriter(_PyUnicodeWriter *writer,
+ PyObject *obj,
+ PyObject *format_spec,
+ Py_ssize_t start, Py_ssize_t end)
+{
+ InternalFormatSpec format;
+
+ /* check for the special case of zero length format spec, make
+ it equivalent to str(obj) */
+ if (start == end)
+ return format_obj(obj, writer);
+
+ /* parse the format_spec */
+ if (!parse_internal_render_format_spec(format_spec, start, end,
+ &format, '\0', '>'))
+ return -1;
+
+ /* type conversion? */
+ switch (format.type) {
+ case '\0': /* No format code: like 'g', but with at least one decimal. */
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ case 'g':
+ case 'G':
+ case 'n':
+ /* no conversion, already a complex. do the formatting */
+ return format_complex_internal(obj, &format, writer);
+
+ default:
+ /* unknown */
+ unknown_presentation_type(format.type, Py_TYPE(obj)->tp_name);
+ return -1;
+ }
+}
diff --git a/contrib/tools/python3/src/Python/frozen.c b/contrib/tools/python3/src/Python/frozen.c
new file mode 100644
index 00000000000..228a11019cf
--- /dev/null
+++ b/contrib/tools/python3/src/Python/frozen.c
@@ -0,0 +1,50 @@
+
+/* Dummy frozen modules initializer */
+
+#include "Python.h"
+#include "importlib.h"
+#include "importlib_external.h"
+#include "importlib_zipimport.h"
+
+/* In order to test the support for frozen modules, by default we
+ define a single frozen module, __hello__. Loading it will print
+ some famous words... */
+
+/* To regenerate this data after the bytecode or marshal format has changed,
+ go to ../Tools/freeze/ and freeze the flag.py file; then copy and paste
+ the appropriate bytes from M___main__.c. */
+
+static unsigned char M___hello__[] = {
+ 227,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,2,0,0,0,64,0,0,0,115,16,0,0,0,100,0,
+ 90,0,101,1,100,1,131,1,1,0,100,2,83,0,41,3,
+ 84,122,12,72,101,108,108,111,32,119,111,114,108,100,33,78,
+ 41,2,218,11,105,110,105,116,105,97,108,105,122,101,100,218,
+ 5,112,114,105,110,116,169,0,114,3,0,0,0,114,3,0,
+ 0,0,250,20,84,111,111,108,115,47,102,114,101,101,122,101,
+ 47,102,108,97,103,46,112,121,218,8,60,109,111,100,117,108,
+ 101,62,1,0,0,0,115,2,0,0,0,4,1,
+};
+
+#define SIZE (int)sizeof(M___hello__)
+
+static const struct _frozen _PyImport_FrozenModules[] = {
+ /* importlib */
+ {"_frozen_importlib", _Py_M__importlib_bootstrap,
+ (int)sizeof(_Py_M__importlib_bootstrap)},
+ {"_frozen_importlib_external", _Py_M__importlib_bootstrap_external,
+ (int)sizeof(_Py_M__importlib_bootstrap_external)},
+ {"zipimport", _Py_M__zipimport,
+ (int)sizeof(_Py_M__zipimport)},
+ /* Test module */
+ {"__hello__", M___hello__, SIZE},
+ /* Test package (negative size indicates package-ness) */
+ {"__phello__", M___hello__, -SIZE},
+ {"__phello__.spam", M___hello__, SIZE},
+ {0, 0, 0} /* sentinel */
+};
+
+/* Embedding apps may change this pointer to point to their favorite
+ collection of frozen modules: */
+
+const struct _frozen *PyImport_FrozenModules = _PyImport_FrozenModules;
diff --git a/contrib/tools/python3/src/Python/frozenmain.c b/contrib/tools/python3/src/Python/frozenmain.c
new file mode 100644
index 00000000000..dd04d609d24
--- /dev/null
+++ b/contrib/tools/python3/src/Python/frozenmain.c
@@ -0,0 +1,129 @@
+
+/* Python interpreter main program for frozen scripts */
+
+#include "Python.h"
+#include "pycore_runtime.h" // _PyRuntime_Initialize()
+#include <locale.h>
+
+#ifdef MS_WINDOWS
+extern void PyWinFreeze_ExeInit(void);
+extern void PyWinFreeze_ExeTerm(void);
+extern int PyInitFrozenExtensions(void);
+#endif
+
+/* Main program */
+
+int
+Py_FrozenMain(int argc, char **argv)
+{
+ PyStatus status = _PyRuntime_Initialize();
+ if (PyStatus_Exception(status)) {
+ Py_ExitStatusException(status);
+ }
+
+ const char *p;
+ int i, n, sts = 1;
+ int inspect = 0;
+ int unbuffered = 0;
+ char *oldloc = NULL;
+ wchar_t **argv_copy = NULL;
+ /* We need a second copies, as Python might modify the first one. */
+ wchar_t **argv_copy2 = NULL;
+
+ if (argc > 0) {
+ argv_copy = PyMem_RawMalloc(sizeof(wchar_t*) * argc);
+ argv_copy2 = PyMem_RawMalloc(sizeof(wchar_t*) * argc);
+ if (!argv_copy || !argv_copy2) {
+ fprintf(stderr, "out of memory\n");
+ goto error;
+ }
+ }
+
+ PyConfig config;
+ PyConfig_InitPythonConfig(&config);
+ config.pathconfig_warnings = 0; /* Suppress errors from getpath.c */
+
+ if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
+ inspect = 1;
+ if ((p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0')
+ unbuffered = 1;
+
+ if (unbuffered) {
+ setbuf(stdin, (char *)NULL);
+ setbuf(stdout, (char *)NULL);
+ setbuf(stderr, (char *)NULL);
+ }
+
+ oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL));
+ if (!oldloc) {
+ fprintf(stderr, "out of memory\n");
+ goto error;
+ }
+
+ setlocale(LC_ALL, "");
+ for (i = 0; i < argc; i++) {
+ argv_copy[i] = Py_DecodeLocale(argv[i], NULL);
+ argv_copy2[i] = argv_copy[i];
+ if (!argv_copy[i]) {
+ fprintf(stderr, "Unable to decode the command line argument #%i\n",
+ i + 1);
+ argc = i;
+ goto error;
+ }
+ }
+ setlocale(LC_ALL, oldloc);
+ PyMem_RawFree(oldloc);
+ oldloc = NULL;
+
+#ifdef MS_WINDOWS
+ PyInitFrozenExtensions();
+#endif /* MS_WINDOWS */
+ if (argc >= 1)
+ Py_SetProgramName(argv_copy[0]);
+
+ status = Py_InitializeFromConfig(&config);
+ PyConfig_Clear(&config);
+ if (PyStatus_Exception(status)) {
+ Py_ExitStatusException(status);
+ }
+
+#ifdef MS_WINDOWS
+ PyWinFreeze_ExeInit();
+#endif
+
+ if (Py_VerboseFlag)
+ fprintf(stderr, "Python %s\n%s\n",
+ Py_GetVersion(), Py_GetCopyright());
+
+ PySys_SetArgv(argc, argv_copy);
+
+ n = PyImport_ImportFrozenModule("__main__");
+ if (n == 0)
+ Py_FatalError("the __main__ module is not frozen");
+ if (n < 0) {
+ PyErr_Print();
+ sts = 1;
+ }
+ else
+ sts = 0;
+
+ if (inspect && isatty((int)fileno(stdin)))
+ sts = PyRun_AnyFile(stdin, "<stdin>") != 0;
+
+#ifdef MS_WINDOWS
+ PyWinFreeze_ExeTerm();
+#endif
+ if (Py_FinalizeEx() < 0) {
+ sts = 120;
+ }
+
+error:
+ PyMem_RawFree(argv_copy);
+ if (argv_copy2) {
+ for (i = 0; i < argc; i++)
+ PyMem_RawFree(argv_copy2[i]);
+ PyMem_RawFree(argv_copy2);
+ }
+ PyMem_RawFree(oldloc);
+ return sts;
+}
diff --git a/contrib/tools/python3/src/Python/future.c b/contrib/tools/python3/src/Python/future.c
new file mode 100644
index 00000000000..1663a38a6fd
--- /dev/null
+++ b/contrib/tools/python3/src/Python/future.c
@@ -0,0 +1,158 @@
+#include "Python.h"
+#include "Python-ast.h"
+#include "node.h"
+#include "token.h"
+#include "graminit.h"
+#include "code.h"
+#include "symtable.h"
+#include "ast.h"
+
+#define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined"
+#define ERR_LATE_FUTURE \
+"from __future__ imports must occur at the beginning of the file"
+
+static int
+future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename)
+{
+ int i;
+ asdl_seq *names;
+
+ assert(s->kind == ImportFrom_kind);
+
+ names = s->v.ImportFrom.names;
+ for (i = 0; i < asdl_seq_LEN(names); i++) {
+ alias_ty name = (alias_ty)asdl_seq_GET(names, i);
+ const char *feature = PyUnicode_AsUTF8(name->name);
+ if (!feature)
+ return 0;
+ if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) {
+ continue;
+ } else if (strcmp(feature, FUTURE_GENERATORS) == 0) {
+ continue;
+ } else if (strcmp(feature, FUTURE_DIVISION) == 0) {
+ continue;
+ } else if (strcmp(feature, FUTURE_ABSOLUTE_IMPORT) == 0) {
+ continue;
+ } else if (strcmp(feature, FUTURE_WITH_STATEMENT) == 0) {
+ continue;
+ } else if (strcmp(feature, FUTURE_PRINT_FUNCTION) == 0) {
+ continue;
+ } else if (strcmp(feature, FUTURE_UNICODE_LITERALS) == 0) {
+ continue;
+ } else if (strcmp(feature, FUTURE_BARRY_AS_BDFL) == 0) {
+ ff->ff_features |= CO_FUTURE_BARRY_AS_BDFL;
+ } else if (strcmp(feature, FUTURE_GENERATOR_STOP) == 0) {
+ continue;
+ } else if (strcmp(feature, FUTURE_ANNOTATIONS) == 0) {
+ ff->ff_features |= CO_FUTURE_ANNOTATIONS;
+ } else if (strcmp(feature, "braces") == 0) {
+ PyErr_SetString(PyExc_SyntaxError,
+ "not a chance");
+ PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset + 1);
+ return 0;
+ } else {
+ PyErr_Format(PyExc_SyntaxError,
+ UNDEFINED_FUTURE_FEATURE, feature);
+ PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset + 1);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int
+future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename)
+{
+ int i, done = 0, prev_line = 0;
+
+ if (!(mod->kind == Module_kind || mod->kind == Interactive_kind))
+ return 1;
+
+ if (asdl_seq_LEN(mod->v.Module.body) == 0)
+ return 1;
+
+ /* A subsequent pass will detect future imports that don't
+ appear at the beginning of the file. There's one case,
+ however, that is easier to handle here: A series of imports
+ joined by semi-colons, where the first import is a future
+ statement but some subsequent import has the future form
+ but is preceded by a regular import.
+ */
+
+ i = 0;
+ if (_PyAST_GetDocString(mod->v.Module.body) != NULL)
+ i++;
+
+ for (; i < asdl_seq_LEN(mod->v.Module.body); i++) {
+ stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i);
+
+ if (done && s->lineno > prev_line)
+ return 1;
+ prev_line = s->lineno;
+
+ /* The tests below will return from this function unless it is
+ still possible to find a future statement. The only things
+ that can precede a future statement are another future
+ statement and a doc string.
+ */
+
+ if (s->kind == ImportFrom_kind) {
+ identifier modname = s->v.ImportFrom.module;
+ if (modname &&
+ _PyUnicode_EqualToASCIIString(modname, "__future__")) {
+ if (done) {
+ PyErr_SetString(PyExc_SyntaxError,
+ ERR_LATE_FUTURE);
+ PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset);
+ return 0;
+ }
+ if (!future_check_features(ff, s, filename))
+ return 0;
+ ff->ff_lineno = s->lineno;
+ }
+ else {
+ done = 1;
+ }
+ }
+ else {
+ done = 1;
+ }
+ }
+ return 1;
+}
+
+
+PyFutureFeatures *
+PyFuture_FromASTObject(mod_ty mod, PyObject *filename)
+{
+ PyFutureFeatures *ff;
+
+ ff = (PyFutureFeatures *)PyObject_Malloc(sizeof(PyFutureFeatures));
+ if (ff == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ ff->ff_features = 0;
+ ff->ff_lineno = -1;
+
+ if (!future_parse(ff, mod, filename)) {
+ PyObject_Free(ff);
+ return NULL;
+ }
+ return ff;
+}
+
+
+PyFutureFeatures *
+PyFuture_FromAST(mod_ty mod, const char *filename_str)
+{
+ PyFutureFeatures *ff;
+ PyObject *filename;
+
+ filename = PyUnicode_DecodeFSDefault(filename_str);
+ if (filename == NULL)
+ return NULL;
+ ff = PyFuture_FromASTObject(mod, filename);
+ Py_DECREF(filename);
+ return ff;
+}
diff --git a/contrib/tools/python3/src/Python/getargs.c b/contrib/tools/python3/src/Python/getargs.c
new file mode 100644
index 00000000000..d4a531a5efb
--- /dev/null
+++ b/contrib/tools/python3/src/Python/getargs.c
@@ -0,0 +1,2870 @@
+
+/* New getargs implementation */
+
+#include "Python.h"
+#include "pycore_tupleobject.h"
+
+#include <ctype.h>
+#include <float.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+int PyArg_Parse(PyObject *, const char *, ...);
+int PyArg_ParseTuple(PyObject *, const char *, ...);
+int PyArg_VaParse(PyObject *, const char *, va_list);
+
+int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
+ const char *, char **, ...);
+int PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *,
+ const char *, char **, va_list);
+
+int _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *,
+ struct _PyArg_Parser *, ...);
+int _PyArg_VaParseTupleAndKeywordsFast(PyObject *, PyObject *,
+ struct _PyArg_Parser *, va_list);
+
+#ifdef HAVE_DECLSPEC_DLL
+/* Export functions */
+PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, const char *, ...);
+PyAPI_FUNC(int) _PyArg_ParseStack_SizeT(PyObject *const *args, Py_ssize_t nargs,
+ const char *format, ...);
+PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs,
+ PyObject *kwnames,
+ struct _PyArg_Parser *parser, ...);
+PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, const char *, ...);
+PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
+ const char *, char **, ...);
+PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...);
+PyAPI_FUNC(int) _PyArg_VaParse_SizeT(PyObject *, const char *, va_list);
+PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
+ const char *, char **, va_list);
+
+PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *, PyObject *,
+ struct _PyArg_Parser *, ...);
+PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *, PyObject *,
+ struct _PyArg_Parser *, va_list);
+#endif
+
+#define FLAG_COMPAT 1
+#define FLAG_SIZE_T 2
+
+typedef int (*destr_t)(PyObject *, void *);
+
+
+/* Keep track of "objects" that have been allocated or initialized and
+ which will need to be deallocated or cleaned up somehow if overall
+ parsing fails.
+*/
+typedef struct {
+ void *item;
+ destr_t destructor;
+} freelistentry_t;
+
+typedef struct {
+ freelistentry_t *entries;
+ int first_available;
+ int entries_malloced;
+} freelist_t;
+
+#define STATIC_FREELIST_ENTRIES 8
+
+/* Forward */
+static int vgetargs1_impl(PyObject *args, PyObject *const *stack, Py_ssize_t nargs,
+ const char *format, va_list *p_va, int flags);
+static int vgetargs1(PyObject *, const char *, va_list *, int);
+static void seterror(Py_ssize_t, const char *, int *, const char *, const char *);
+static const char *convertitem(PyObject *, const char **, va_list *, int, int *,
+ char *, size_t, freelist_t *);
+static const char *converttuple(PyObject *, const char **, va_list *, int,
+ int *, char *, size_t, int, freelist_t *);
+static const char *convertsimple(PyObject *, const char **, va_list *, int,
+ char *, size_t, freelist_t *);
+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 *, char **, va_list *, int);
+static int vgetargskeywordsfast(PyObject *, PyObject *,
+ struct _PyArg_Parser *, va_list *, int);
+static int vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs,
+ PyObject *keywords, PyObject *kwnames,
+ struct _PyArg_Parser *parser,
+ va_list *p_va, int flags);
+static const char *skipitem(const char **, va_list *, int);
+
+int
+PyArg_Parse(PyObject *args, const char *format, ...)
+{
+ int retval;
+ va_list va;
+
+ va_start(va, format);
+ retval = vgetargs1(args, format, &va, FLAG_COMPAT);
+ va_end(va);
+ return retval;
+}
+
+PyAPI_FUNC(int)
+_PyArg_Parse_SizeT(PyObject *args, const char *format, ...)
+{
+ int retval;
+ va_list va;
+
+ va_start(va, format);
+ retval = vgetargs1(args, format, &va, FLAG_COMPAT|FLAG_SIZE_T);
+ va_end(va);
+ return retval;
+}
+
+
+int
+PyArg_ParseTuple(PyObject *args, const char *format, ...)
+{
+ int retval;
+ va_list va;
+
+ va_start(va, format);
+ retval = vgetargs1(args, format, &va, 0);
+ va_end(va);
+ return retval;
+}
+
+PyAPI_FUNC(int)
+_PyArg_ParseTuple_SizeT(PyObject *args, const char *format, ...)
+{
+ int retval;
+ va_list va;
+
+ va_start(va, format);
+ retval = vgetargs1(args, format, &va, FLAG_SIZE_T);
+ va_end(va);
+ return retval;
+}
+
+
+int
+_PyArg_ParseStack(PyObject *const *args, Py_ssize_t nargs, const char *format, ...)
+{
+ int retval;
+ va_list va;
+
+ va_start(va, format);
+ retval = vgetargs1_impl(NULL, args, nargs, format, &va, 0);
+ va_end(va);
+ return retval;
+}
+
+PyAPI_FUNC(int)
+_PyArg_ParseStack_SizeT(PyObject *const *args, Py_ssize_t nargs, const char *format, ...)
+{
+ int retval;
+ va_list va;
+
+ va_start(va, format);
+ retval = vgetargs1_impl(NULL, args, nargs, format, &va, FLAG_SIZE_T);
+ va_end(va);
+ return retval;
+}
+
+
+int
+PyArg_VaParse(PyObject *args, const char *format, va_list va)
+{
+ va_list lva;
+ int retval;
+
+ va_copy(lva, va);
+
+ retval = vgetargs1(args, format, &lva, 0);
+ va_end(lva);
+ return retval;
+}
+
+PyAPI_FUNC(int)
+_PyArg_VaParse_SizeT(PyObject *args, const char *format, va_list va)
+{
+ va_list lva;
+ int retval;
+
+ va_copy(lva, va);
+
+ retval = vgetargs1(args, format, &lva, FLAG_SIZE_T);
+ va_end(lva);
+ return retval;
+}
+
+
+/* Handle cleanup of allocated memory in case of exception */
+
+static int
+cleanup_ptr(PyObject *self, void *ptr)
+{
+ if (ptr) {
+ PyMem_FREE(ptr);
+ }
+ return 0;
+}
+
+static int
+cleanup_buffer(PyObject *self, void *ptr)
+{
+ Py_buffer *buf = (Py_buffer *)ptr;
+ if (buf) {
+ PyBuffer_Release(buf);
+ }
+ return 0;
+}
+
+static int
+addcleanup(void *ptr, freelist_t *freelist, destr_t destructor)
+{
+ int index;
+
+ index = freelist->first_available;
+ freelist->first_available += 1;
+
+ freelist->entries[index].item = ptr;
+ freelist->entries[index].destructor = destructor;
+
+ return 0;
+}
+
+static int
+cleanreturn(int retval, freelist_t *freelist)
+{
+ int index;
+
+ if (retval == 0) {
+ /* A failure occurred, therefore execute all of the cleanup
+ functions.
+ */
+ for (index = 0; index < freelist->first_available; ++index) {
+ freelist->entries[index].destructor(NULL,
+ freelist->entries[index].item);
+ }
+ }
+ if (freelist->entries_malloced)
+ PyMem_FREE(freelist->entries);
+ return retval;
+}
+
+
+static int
+vgetargs1_impl(PyObject *compat_args, PyObject *const *stack, Py_ssize_t nargs, const char *format,
+ va_list *p_va, int flags)
+{
+ char msgbuf[256];
+ int levels[32];
+ const char *fname = NULL;
+ const char *message = NULL;
+ int min = -1;
+ int max = 0;
+ int level = 0;
+ int endfmt = 0;
+ const char *formatsave = format;
+ Py_ssize_t i;
+ const char *msg;
+ int compat = flags & FLAG_COMPAT;
+ freelistentry_t static_entries[STATIC_FREELIST_ENTRIES];
+ freelist_t freelist;
+
+ assert(nargs == 0 || stack != NULL);
+
+ freelist.entries = static_entries;
+ freelist.first_available = 0;
+ freelist.entries_malloced = 0;
+
+ flags = flags & ~FLAG_COMPAT;
+
+ while (endfmt == 0) {
+ int c = *format++;
+ switch (c) {
+ case '(':
+ if (level == 0)
+ max++;
+ level++;
+ if (level >= 30)
+ Py_FatalError("too many tuple nesting levels "
+ "in argument format string");
+ break;
+ case ')':
+ if (level == 0)
+ Py_FatalError("excess ')' in getargs format");
+ else
+ level--;
+ break;
+ case '\0':
+ endfmt = 1;
+ break;
+ case ':':
+ fname = format;
+ endfmt = 1;
+ break;
+ case ';':
+ message = format;
+ endfmt = 1;
+ break;
+ case '|':
+ if (level == 0)
+ min = max;
+ break;
+ default:
+ if (level == 0) {
+ if (Py_ISALPHA(c))
+ if (c != 'e') /* skip encoded */
+ max++;
+ }
+ break;
+ }
+ }
+
+ if (level != 0)
+ Py_FatalError(/* '(' */ "missing ')' in getargs format");
+
+ if (min < 0)
+ min = max;
+
+ format = formatsave;
+
+ if (max > STATIC_FREELIST_ENTRIES) {
+ freelist.entries = PyMem_NEW(freelistentry_t, max);
+ if (freelist.entries == NULL) {
+ PyErr_NoMemory();
+ return 0;
+ }
+ freelist.entries_malloced = 1;
+ }
+
+ if (compat) {
+ if (max == 0) {
+ if (compat_args == NULL)
+ return 1;
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%s takes no arguments",
+ fname==NULL ? "function" : fname,
+ fname==NULL ? "" : "()");
+ return cleanreturn(0, &freelist);
+ }
+ else if (min == 1 && max == 1) {
+ if (compat_args == NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%s takes at least one argument",
+ fname==NULL ? "function" : fname,
+ fname==NULL ? "" : "()");
+ return cleanreturn(0, &freelist);
+ }
+ msg = convertitem(compat_args, &format, p_va, flags, levels,
+ msgbuf, sizeof(msgbuf), &freelist);
+ if (msg == NULL)
+ return cleanreturn(1, &freelist);
+ seterror(levels[0], msg, levels+1, fname, message);
+ return cleanreturn(0, &freelist);
+ }
+ else {
+ PyErr_SetString(PyExc_SystemError,
+ "old style getargs format uses new features");
+ return cleanreturn(0, &freelist);
+ }
+ }
+
+ if (nargs < min || max < nargs) {
+ if (message == NULL)
+ PyErr_Format(PyExc_TypeError,
+ "%.150s%s takes %s %d argument%s (%zd given)",
+ fname==NULL ? "function" : fname,
+ fname==NULL ? "" : "()",
+ min==max ? "exactly"
+ : nargs < min ? "at least" : "at most",
+ nargs < min ? min : max,
+ (nargs < min ? min : max) == 1 ? "" : "s",
+ nargs);
+ else
+ PyErr_SetString(PyExc_TypeError, message);
+ return cleanreturn(0, &freelist);
+ }
+
+ for (i = 0; i < nargs; i++) {
+ if (*format == '|')
+ format++;
+ msg = convertitem(stack[i], &format, p_va,
+ flags, levels, msgbuf,
+ sizeof(msgbuf), &freelist);
+ if (msg) {
+ seterror(i+1, msg, levels, fname, message);
+ return cleanreturn(0, &freelist);
+ }
+ }
+
+ if (*format != '\0' && !Py_ISALPHA(*format) &&
+ *format != '(' &&
+ *format != '|' && *format != ':' && *format != ';') {
+ PyErr_Format(PyExc_SystemError,
+ "bad format string: %.200s", formatsave);
+ return cleanreturn(0, &freelist);
+ }
+
+ return cleanreturn(1, &freelist);
+}
+
+static int
+vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
+{
+ PyObject **stack;
+ Py_ssize_t nargs;
+
+ if (!(flags & FLAG_COMPAT)) {
+ assert(args != NULL);
+
+ if (!PyTuple_Check(args)) {
+ PyErr_SetString(PyExc_SystemError,
+ "new style getargs format but argument is not a tuple");
+ return 0;
+ }
+
+ stack = _PyTuple_ITEMS(args);
+ nargs = PyTuple_GET_SIZE(args);
+ }
+ else {
+ stack = NULL;
+ nargs = 0;
+ }
+
+ return vgetargs1_impl(args, stack, nargs, format, p_va, flags);
+}
+
+
+static void
+seterror(Py_ssize_t iarg, const char *msg, int *levels, const char *fname,
+ const char *message)
+{
+ char buf[512];
+ int i;
+ char *p = buf;
+
+ if (PyErr_Occurred())
+ return;
+ else if (message == NULL) {
+ if (fname != NULL) {
+ PyOS_snprintf(p, sizeof(buf), "%.200s() ", fname);
+ p += strlen(p);
+ }
+ if (iarg != 0) {
+ PyOS_snprintf(p, sizeof(buf) - (p - buf),
+ "argument %" PY_FORMAT_SIZE_T "d", iarg);
+ i = 0;
+ p += strlen(p);
+ while (i < 32 && levels[i] > 0 && (int)(p-buf) < 220) {
+ PyOS_snprintf(p, sizeof(buf) - (p - buf),
+ ", item %d", levels[i]-1);
+ p += strlen(p);
+ i++;
+ }
+ }
+ else {
+ PyOS_snprintf(p, sizeof(buf) - (p - buf), "argument");
+ p += strlen(p);
+ }
+ PyOS_snprintf(p, sizeof(buf) - (p - buf), " %.256s", msg);
+ message = buf;
+ }
+ if (msg[0] == '(') {
+ PyErr_SetString(PyExc_SystemError, message);
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError, message);
+ }
+}
+
+
+/* Convert a tuple argument.
+ On entry, *p_format points to the character _after_ the opening '('.
+ On successful exit, *p_format points to the closing ')'.
+ If successful:
+ *p_format and *p_va are updated,
+ *levels and *msgbuf are untouched,
+ and NULL is returned.
+ If the argument is invalid:
+ *p_format is unchanged,
+ *p_va is undefined,
+ *levels is a 0-terminated list of item numbers,
+ *msgbuf contains an error message, whose format is:
+ "must be <typename1>, not <typename2>", where:
+ <typename1> is the name of the expected type, and
+ <typename2> is the name of the actual type,
+ and msgbuf is returned.
+*/
+
+static const char *
+converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
+ int *levels, char *msgbuf, size_t bufsize, int toplevel,
+ freelist_t *freelist)
+{
+ int level = 0;
+ int n = 0;
+ const char *format = *p_format;
+ int i;
+ Py_ssize_t len;
+
+ for (;;) {
+ int c = *format++;
+ if (c == '(') {
+ if (level == 0)
+ n++;
+ level++;
+ }
+ else if (c == ')') {
+ if (level == 0)
+ break;
+ level--;
+ }
+ else if (c == ':' || c == ';' || c == '\0')
+ break;
+ else if (level == 0 && Py_ISALPHA(c))
+ n++;
+ }
+
+ if (!PySequence_Check(arg) || PyBytes_Check(arg)) {
+ levels[0] = 0;
+ PyOS_snprintf(msgbuf, bufsize,
+ toplevel ? "expected %d arguments, not %.50s" :
+ "must be %d-item sequence, not %.50s",
+ n,
+ arg == Py_None ? "None" : Py_TYPE(arg)->tp_name);
+ return msgbuf;
+ }
+
+ len = PySequence_Size(arg);
+ if (len != n) {
+ levels[0] = 0;
+ if (toplevel) {
+ PyOS_snprintf(msgbuf, bufsize,
+ "expected %d argument%s, not %" PY_FORMAT_SIZE_T "d",
+ n,
+ n == 1 ? "" : "s",
+ len);
+ }
+ else {
+ PyOS_snprintf(msgbuf, bufsize,
+ "must be sequence of length %d, "
+ "not %" PY_FORMAT_SIZE_T "d",
+ n, len);
+ }
+ return msgbuf;
+ }
+
+ format = *p_format;
+ for (i = 0; i < n; i++) {
+ const char *msg;
+ PyObject *item;
+ item = PySequence_GetItem(arg, i);
+ if (item == NULL) {
+ PyErr_Clear();
+ levels[0] = i+1;
+ levels[1] = 0;
+ strncpy(msgbuf, "is not retrievable", bufsize);
+ return msgbuf;
+ }
+ msg = convertitem(item, &format, p_va, flags, levels+1,
+ msgbuf, bufsize, freelist);
+ /* PySequence_GetItem calls tp->sq_item, which INCREFs */
+ Py_XDECREF(item);
+ if (msg != NULL) {
+ levels[0] = i+1;
+ return msg;
+ }
+ }
+
+ *p_format = format;
+ return NULL;
+}
+
+
+/* Convert a single item. */
+
+static const char *
+convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags,
+ int *levels, char *msgbuf, size_t bufsize, freelist_t *freelist)
+{
+ const char *msg;
+ const char *format = *p_format;
+
+ if (*format == '(' /* ')' */) {
+ format++;
+ msg = converttuple(arg, &format, p_va, flags, levels, msgbuf,
+ bufsize, 0, freelist);
+ if (msg == NULL)
+ format++;
+ }
+ else {
+ msg = convertsimple(arg, &format, p_va, flags,
+ msgbuf, bufsize, freelist);
+ if (msg != NULL)
+ levels[0] = 0;
+ }
+ if (msg == NULL)
+ *p_format = format;
+ return msg;
+}
+
+
+
+/* Format an error message generated by convertsimple().
+ displayname must be UTF-8 encoded.
+*/
+
+void
+_PyArg_BadArgument(const char *fname, const char *displayname,
+ const char *expected, PyObject *arg)
+{
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() %.200s must be %.50s, not %.50s",
+ fname, displayname, expected,
+ arg == Py_None ? "None" : Py_TYPE(arg)->tp_name);
+}
+
+static const char *
+converterr(const char *expected, PyObject *arg, char *msgbuf, size_t bufsize)
+{
+ assert(expected != NULL);
+ assert(arg != NULL);
+ if (expected[0] == '(') {
+ PyOS_snprintf(msgbuf, bufsize,
+ "%.100s", expected);
+ }
+ else {
+ PyOS_snprintf(msgbuf, bufsize,
+ "must be %.50s, not %.50s", expected,
+ arg == Py_None ? "None" : Py_TYPE(arg)->tp_name);
+ }
+ return msgbuf;
+}
+
+#define CONV_UNICODE "(unicode conversion error)"
+
+/* Explicitly check for float arguments when integers are expected.
+ Return 1 for error, 0 if ok.
+ XXX Should be removed after the end of the deprecation period in
+ _PyLong_FromNbIndexOrNbInt. */
+static int
+float_argument_error(PyObject *arg)
+{
+ if (PyFloat_Check(arg)) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument expected, got float" );
+ return 1;
+ }
+ else
+ return 0;
+}
+
+/* Convert a non-tuple argument. Return NULL if conversion went OK,
+ or a string with a message describing the failure. The message is
+ formatted as "must be <desired type>, not <actual type>".
+ When failing, an exception may or may not have been raised.
+ Don't call if a tuple is expected.
+
+ When you add new format codes, please don't forget poor skipitem() below.
+*/
+
+static const char *
+convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
+ char *msgbuf, size_t bufsize, freelist_t *freelist)
+{
+ /* For # codes */
+#define FETCH_SIZE int *q=NULL;Py_ssize_t *q2=NULL;\
+ if (flags & FLAG_SIZE_T) q2=va_arg(*p_va, Py_ssize_t*); \
+ else { \
+ if (PyErr_WarnEx(PyExc_DeprecationWarning, \
+ "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) { \
+ return NULL; \
+ } \
+ q=va_arg(*p_va, int*); \
+ }
+#define STORE_SIZE(s) \
+ if (flags & FLAG_SIZE_T) \
+ *q2=s; \
+ else { \
+ if (INT_MAX < s) { \
+ PyErr_SetString(PyExc_OverflowError, \
+ "size does not fit in an int"); \
+ return converterr("", arg, msgbuf, bufsize); \
+ } \
+ *q = (int)s; \
+ }
+#define BUFFER_LEN ((flags & FLAG_SIZE_T) ? *q2:*q)
+#define RETURN_ERR_OCCURRED return msgbuf
+
+ const char *format = *p_format;
+ char c = *format++;
+ const char *sarg;
+
+ switch (c) {
+
+ case 'b': { /* unsigned byte -- very short int */
+ char *p = va_arg(*p_va, char *);
+ long ival;
+ if (float_argument_error(arg))
+ RETURN_ERR_OCCURRED;
+ ival = PyLong_AsLong(arg);
+ if (ival == -1 && PyErr_Occurred())
+ RETURN_ERR_OCCURRED;
+ else if (ival < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "unsigned byte integer is less than minimum");
+ RETURN_ERR_OCCURRED;
+ }
+ else if (ival > UCHAR_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "unsigned byte integer is greater than maximum");
+ RETURN_ERR_OCCURRED;
+ }
+ else
+ *p = (unsigned char) ival;
+ break;
+ }
+
+ case 'B': {/* byte sized bitfield - both signed and unsigned
+ values allowed */
+ char *p = va_arg(*p_va, char *);
+ long ival;
+ if (float_argument_error(arg))
+ RETURN_ERR_OCCURRED;
+ ival = PyLong_AsUnsignedLongMask(arg);
+ if (ival == -1 && PyErr_Occurred())
+ RETURN_ERR_OCCURRED;
+ else
+ *p = (unsigned char) ival;
+ break;
+ }
+
+ case 'h': {/* signed short int */
+ short *p = va_arg(*p_va, short *);
+ long ival;
+ if (float_argument_error(arg))
+ RETURN_ERR_OCCURRED;
+ ival = PyLong_AsLong(arg);
+ if (ival == -1 && PyErr_Occurred())
+ RETURN_ERR_OCCURRED;
+ else if (ival < SHRT_MIN) {
+ PyErr_SetString(PyExc_OverflowError,
+ "signed short integer is less than minimum");
+ RETURN_ERR_OCCURRED;
+ }
+ else if (ival > SHRT_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "signed short integer is greater than maximum");
+ RETURN_ERR_OCCURRED;
+ }
+ else
+ *p = (short) ival;
+ break;
+ }
+
+ case 'H': { /* short int sized bitfield, both signed and
+ unsigned allowed */
+ unsigned short *p = va_arg(*p_va, unsigned short *);
+ long ival;
+ if (float_argument_error(arg))
+ RETURN_ERR_OCCURRED;
+ ival = PyLong_AsUnsignedLongMask(arg);
+ if (ival == -1 && PyErr_Occurred())
+ RETURN_ERR_OCCURRED;
+ else
+ *p = (unsigned short) ival;
+ break;
+ }
+
+ case 'i': {/* signed int */
+ int *p = va_arg(*p_va, int *);
+ long ival;
+ if (float_argument_error(arg))
+ RETURN_ERR_OCCURRED;
+ ival = PyLong_AsLong(arg);
+ if (ival == -1 && PyErr_Occurred())
+ RETURN_ERR_OCCURRED;
+ else if (ival > INT_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "signed integer is greater than maximum");
+ RETURN_ERR_OCCURRED;
+ }
+ else if (ival < INT_MIN) {
+ PyErr_SetString(PyExc_OverflowError,
+ "signed integer is less than minimum");
+ RETURN_ERR_OCCURRED;
+ }
+ else
+ *p = ival;
+ break;
+ }
+
+ case 'I': { /* int sized bitfield, both signed and
+ unsigned allowed */
+ unsigned int *p = va_arg(*p_va, unsigned int *);
+ unsigned int ival;
+ if (float_argument_error(arg))
+ RETURN_ERR_OCCURRED;
+ ival = (unsigned int)PyLong_AsUnsignedLongMask(arg);
+ if (ival == (unsigned int)-1 && PyErr_Occurred())
+ RETURN_ERR_OCCURRED;
+ else
+ *p = ival;
+ break;
+ }
+
+ case 'n': /* Py_ssize_t */
+ {
+ PyObject *iobj;
+ Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *);
+ Py_ssize_t ival = -1;
+ if (float_argument_error(arg))
+ RETURN_ERR_OCCURRED;
+ iobj = PyNumber_Index(arg);
+ if (iobj != NULL) {
+ ival = PyLong_AsSsize_t(iobj);
+ Py_DECREF(iobj);
+ }
+ if (ival == -1 && PyErr_Occurred())
+ RETURN_ERR_OCCURRED;
+ *p = ival;
+ break;
+ }
+ case 'l': {/* long int */
+ long *p = va_arg(*p_va, long *);
+ long ival;
+ if (float_argument_error(arg))
+ RETURN_ERR_OCCURRED;
+ ival = PyLong_AsLong(arg);
+ if (ival == -1 && PyErr_Occurred())
+ RETURN_ERR_OCCURRED;
+ else
+ *p = ival;
+ break;
+ }
+
+ case 'k': { /* long sized bitfield */
+ unsigned long *p = va_arg(*p_va, unsigned long *);
+ unsigned long ival;
+ if (PyLong_Check(arg))
+ ival = PyLong_AsUnsignedLongMask(arg);
+ else
+ return converterr("int", arg, msgbuf, bufsize);
+ *p = ival;
+ break;
+ }
+
+ case 'L': {/* long long */
+ long long *p = va_arg( *p_va, long long * );
+ long long ival;
+ if (float_argument_error(arg))
+ RETURN_ERR_OCCURRED;
+ ival = PyLong_AsLongLong(arg);
+ if (ival == (long long)-1 && PyErr_Occurred())
+ RETURN_ERR_OCCURRED;
+ else
+ *p = ival;
+ break;
+ }
+
+ case 'K': { /* long long sized bitfield */
+ unsigned long long *p = va_arg(*p_va, unsigned long long *);
+ unsigned long long ival;
+ if (PyLong_Check(arg))
+ ival = PyLong_AsUnsignedLongLongMask(arg);
+ else
+ return converterr("int", arg, msgbuf, bufsize);
+ *p = ival;
+ break;
+ }
+
+ case 'f': {/* float */
+ float *p = va_arg(*p_va, float *);
+ double dval = PyFloat_AsDouble(arg);
+ if (dval == -1.0 && PyErr_Occurred())
+ RETURN_ERR_OCCURRED;
+ else
+ *p = (float) dval;
+ break;
+ }
+
+ case 'd': {/* double */
+ double *p = va_arg(*p_va, double *);
+ double dval = PyFloat_AsDouble(arg);
+ if (dval == -1.0 && PyErr_Occurred())
+ RETURN_ERR_OCCURRED;
+ else
+ *p = dval;
+ break;
+ }
+
+ case 'D': {/* complex double */
+ Py_complex *p = va_arg(*p_va, Py_complex *);
+ Py_complex cval;
+ cval = PyComplex_AsCComplex(arg);
+ if (PyErr_Occurred())
+ RETURN_ERR_OCCURRED;
+ else
+ *p = cval;
+ break;
+ }
+
+ case 'c': {/* char */
+ char *p = va_arg(*p_va, char *);
+ if (PyBytes_Check(arg) && PyBytes_Size(arg) == 1)
+ *p = PyBytes_AS_STRING(arg)[0];
+ else if (PyByteArray_Check(arg) && PyByteArray_Size(arg) == 1)
+ *p = PyByteArray_AS_STRING(arg)[0];
+ else
+ return converterr("a byte string of length 1", arg, msgbuf, bufsize);
+ break;
+ }
+
+ case 'C': {/* unicode char */
+ int *p = va_arg(*p_va, int *);
+ int kind;
+ const void *data;
+
+ if (!PyUnicode_Check(arg))
+ return converterr("a unicode character", arg, msgbuf, bufsize);
+
+ if (PyUnicode_READY(arg))
+ RETURN_ERR_OCCURRED;
+
+ if (PyUnicode_GET_LENGTH(arg) != 1)
+ return converterr("a unicode character", arg, msgbuf, bufsize);
+
+ kind = PyUnicode_KIND(arg);
+ data = PyUnicode_DATA(arg);
+ *p = PyUnicode_READ(kind, data, 0);
+ break;
+ }
+
+ case 'p': {/* boolean *p*redicate */
+ int *p = va_arg(*p_va, int *);
+ int val = PyObject_IsTrue(arg);
+ if (val > 0)
+ *p = 1;
+ else if (val == 0)
+ *p = 0;
+ else
+ RETURN_ERR_OCCURRED;
+ break;
+ }
+
+ /* XXX WAAAAH! 's', 'y', 'z', 'u', 'Z', 'e', 'w' codes all
+ need to be cleaned up! */
+
+ case 'y': {/* any bytes-like object */
+ void **p = (void **)va_arg(*p_va, char **);
+ const char *buf;
+ Py_ssize_t count;
+ if (*format == '*') {
+ if (getbuffer(arg, (Py_buffer*)p, &buf) < 0)
+ return converterr(buf, arg, msgbuf, bufsize);
+ format++;
+ if (addcleanup(p, freelist, cleanup_buffer)) {
+ return converterr(
+ "(cleanup problem)",
+ arg, msgbuf, bufsize);
+ }
+ break;
+ }
+ count = convertbuffer(arg, (const void **)p, &buf);
+ if (count < 0)
+ return converterr(buf, arg, msgbuf, bufsize);
+ if (*format == '#') {
+ FETCH_SIZE;
+ STORE_SIZE(count);
+ format++;
+ } else {
+ if (strlen(*p) != (size_t)count) {
+ PyErr_SetString(PyExc_ValueError, "embedded null byte");
+ RETURN_ERR_OCCURRED;
+ }
+ }
+ break;
+ }
+
+ case 's': /* text string or bytes-like object */
+ case 'z': /* text string, bytes-like object or None */
+ {
+ if (*format == '*') {
+ /* "s*" or "z*" */
+ Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
+
+ if (c == 'z' && arg == Py_None)
+ PyBuffer_FillInfo(p, NULL, NULL, 0, 1, 0);
+ else if (PyUnicode_Check(arg)) {
+ Py_ssize_t len;
+ sarg = PyUnicode_AsUTF8AndSize(arg, &len);
+ if (sarg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf, bufsize);
+ PyBuffer_FillInfo(p, arg, (void *)sarg, len, 1, 0);
+ }
+ else { /* any bytes-like object */
+ const char *buf;
+ if (getbuffer(arg, p, &buf) < 0)
+ return converterr(buf, arg, msgbuf, bufsize);
+ }
+ if (addcleanup(p, freelist, cleanup_buffer)) {
+ return converterr(
+ "(cleanup problem)",
+ arg, msgbuf, bufsize);
+ }
+ format++;
+ } else if (*format == '#') { /* a string or read-only bytes-like object */
+ /* "s#" or "z#" */
+ const void **p = (const void **)va_arg(*p_va, const char **);
+ FETCH_SIZE;
+
+ if (c == 'z' && arg == Py_None) {
+ *p = NULL;
+ STORE_SIZE(0);
+ }
+ else if (PyUnicode_Check(arg)) {
+ Py_ssize_t len;
+ sarg = PyUnicode_AsUTF8AndSize(arg, &len);
+ if (sarg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf, bufsize);
+ *p = sarg;
+ STORE_SIZE(len);
+ }
+ else { /* read-only bytes-like object */
+ /* XXX Really? */
+ const char *buf;
+ Py_ssize_t count = convertbuffer(arg, p, &buf);
+ if (count < 0)
+ return converterr(buf, arg, msgbuf, bufsize);
+ STORE_SIZE(count);
+ }
+ format++;
+ } else {
+ /* "s" or "z" */
+ const char **p = va_arg(*p_va, const char **);
+ Py_ssize_t len;
+ sarg = NULL;
+
+ if (c == 'z' && arg == Py_None)
+ *p = NULL;
+ else if (PyUnicode_Check(arg)) {
+ sarg = PyUnicode_AsUTF8AndSize(arg, &len);
+ if (sarg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf, bufsize);
+ if (strlen(sarg) != (size_t)len) {
+ PyErr_SetString(PyExc_ValueError, "embedded null character");
+ RETURN_ERR_OCCURRED;
+ }
+ *p = sarg;
+ }
+ else
+ return converterr(c == 'z' ? "str or None" : "str",
+ arg, msgbuf, bufsize);
+ }
+ break;
+ }
+
+ case 'u': /* raw unicode buffer (Py_UNICODE *) */
+ case 'Z': /* raw unicode buffer or None */
+ {
+ // TODO: Raise DeprecationWarning
+_Py_COMP_DIAG_PUSH
+_Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
+
+ if (*format == '#') {
+ /* "u#" or "Z#" */
+ FETCH_SIZE;
+
+ if (c == 'Z' && arg == Py_None) {
+ *p = NULL;
+ STORE_SIZE(0);
+ }
+ else if (PyUnicode_Check(arg)) {
+ Py_ssize_t len;
+ *p = PyUnicode_AsUnicodeAndSize(arg, &len);
+ if (*p == NULL)
+ RETURN_ERR_OCCURRED;
+ STORE_SIZE(len);
+ }
+ else
+ return converterr(c == 'Z' ? "str or None" : "str",
+ arg, msgbuf, bufsize);
+ format++;
+ } else {
+ /* "u" or "Z" */
+ if (c == 'Z' && arg == Py_None)
+ *p = NULL;
+ else if (PyUnicode_Check(arg)) {
+ Py_ssize_t len;
+ *p = PyUnicode_AsUnicodeAndSize(arg, &len);
+ if (*p == NULL)
+ RETURN_ERR_OCCURRED;
+ if (wcslen(*p) != (size_t)len) {
+ PyErr_SetString(PyExc_ValueError, "embedded null character");
+ RETURN_ERR_OCCURRED;
+ }
+ } else
+ return converterr(c == 'Z' ? "str or None" : "str",
+ arg, msgbuf, bufsize);
+ }
+ break;
+_Py_COMP_DIAG_POP
+ }
+
+ case 'e': {/* encoded string */
+ char **buffer;
+ const char *encoding;
+ PyObject *s;
+ int recode_strings;
+ Py_ssize_t size;
+ const char *ptr;
+
+ /* Get 'e' parameter: the encoding name */
+ encoding = (const char *)va_arg(*p_va, const char *);
+ if (encoding == NULL)
+ encoding = PyUnicode_GetDefaultEncoding();
+
+ /* Get output buffer parameter:
+ 's' (recode all objects via Unicode) or
+ 't' (only recode non-string objects)
+ */
+ if (*format == 's')
+ recode_strings = 1;
+ else if (*format == 't')
+ recode_strings = 0;
+ else
+ return converterr(
+ "(unknown parser marker combination)",
+ arg, msgbuf, bufsize);
+ buffer = (char **)va_arg(*p_va, char **);
+ format++;
+ if (buffer == NULL)
+ return converterr("(buffer is NULL)",
+ arg, msgbuf, bufsize);
+
+ /* Encode object */
+ if (!recode_strings &&
+ (PyBytes_Check(arg) || PyByteArray_Check(arg))) {
+ s = arg;
+ Py_INCREF(s);
+ if (PyBytes_Check(arg)) {
+ size = PyBytes_GET_SIZE(s);
+ ptr = PyBytes_AS_STRING(s);
+ }
+ else {
+ size = PyByteArray_GET_SIZE(s);
+ ptr = PyByteArray_AS_STRING(s);
+ }
+ }
+ else if (PyUnicode_Check(arg)) {
+ /* Encode object; use default error handling */
+ s = PyUnicode_AsEncodedString(arg,
+ encoding,
+ NULL);
+ if (s == NULL)
+ return converterr("(encoding failed)",
+ arg, msgbuf, bufsize);
+ assert(PyBytes_Check(s));
+ size = PyBytes_GET_SIZE(s);
+ ptr = PyBytes_AS_STRING(s);
+ if (ptr == NULL)
+ ptr = "";
+ }
+ else {
+ return converterr(
+ recode_strings ? "str" : "str, bytes or bytearray",
+ arg, msgbuf, bufsize);
+ }
+
+ /* Write output; output is guaranteed to be 0-terminated */
+ if (*format == '#') {
+ /* Using buffer length parameter '#':
+
+ - if *buffer is NULL, a new buffer of the
+ needed size is allocated and the data
+ copied into it; *buffer is updated to point
+ to the new buffer; the caller is
+ responsible for PyMem_Free()ing it after
+ usage
+
+ - if *buffer is not NULL, the data is
+ copied to *buffer; *buffer_len has to be
+ set to the size of the buffer on input;
+ buffer overflow is signalled with an error;
+ buffer has to provide enough room for the
+ encoded string plus the trailing 0-byte
+
+ - in both cases, *buffer_len is updated to
+ the size of the buffer /excluding/ the
+ trailing 0-byte
+
+ */
+ int *q = NULL; Py_ssize_t *q2 = NULL;
+ if (flags & FLAG_SIZE_T) {
+ q2 = va_arg(*p_va, Py_ssize_t*);
+ }
+ else {
+ if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "PY_SSIZE_T_CLEAN will be required for '#' formats", 1))
+ {
+ Py_DECREF(s);
+ return NULL;
+ }
+ q = va_arg(*p_va, int*);
+ }
+
+ format++;
+ if (q == NULL && q2 == NULL) {
+ Py_DECREF(s);
+ return converterr(
+ "(buffer_len is NULL)",
+ arg, msgbuf, bufsize);
+ }
+ if (*buffer == NULL) {
+ *buffer = PyMem_NEW(char, size + 1);
+ if (*buffer == NULL) {
+ Py_DECREF(s);
+ PyErr_NoMemory();
+ RETURN_ERR_OCCURRED;
+ }
+ if (addcleanup(*buffer, freelist, cleanup_ptr)) {
+ Py_DECREF(s);
+ return converterr(
+ "(cleanup problem)",
+ arg, msgbuf, bufsize);
+ }
+ } else {
+ if (size + 1 > BUFFER_LEN) {
+ Py_DECREF(s);
+ PyErr_Format(PyExc_ValueError,
+ "encoded string too long "
+ "(%zd, maximum length %zd)",
+ (Py_ssize_t)size, (Py_ssize_t)(BUFFER_LEN-1));
+ RETURN_ERR_OCCURRED;
+ }
+ }
+ memcpy(*buffer, ptr, size+1);
+
+ if (flags & FLAG_SIZE_T) {
+ *q2 = size;
+ }
+ else {
+ if (INT_MAX < size) {
+ Py_DECREF(s);
+ PyErr_SetString(PyExc_OverflowError,
+ "size does not fit in an int");
+ return converterr("", arg, msgbuf, bufsize);
+ }
+ *q = (int)size;
+ }
+ } else {
+ /* Using a 0-terminated buffer:
+
+ - the encoded string has to be 0-terminated
+ for this variant to work; if it is not, an
+ error raised
+
+ - a new buffer of the needed size is
+ allocated and the data copied into it;
+ *buffer is updated to point to the new
+ buffer; the caller is responsible for
+ PyMem_Free()ing it after usage
+
+ */
+ if ((Py_ssize_t)strlen(ptr) != size) {
+ Py_DECREF(s);
+ return converterr(
+ "encoded string without null bytes",
+ arg, msgbuf, bufsize);
+ }
+ *buffer = PyMem_NEW(char, size + 1);
+ if (*buffer == NULL) {
+ Py_DECREF(s);
+ PyErr_NoMemory();
+ RETURN_ERR_OCCURRED;
+ }
+ if (addcleanup(*buffer, freelist, cleanup_ptr)) {
+ Py_DECREF(s);
+ return converterr("(cleanup problem)",
+ arg, msgbuf, bufsize);
+ }
+ memcpy(*buffer, ptr, size+1);
+ }
+ Py_DECREF(s);
+ break;
+ }
+
+ case 'S': { /* PyBytes object */
+ PyObject **p = va_arg(*p_va, PyObject **);
+ if (PyBytes_Check(arg))
+ *p = arg;
+ else
+ return converterr("bytes", arg, msgbuf, bufsize);
+ break;
+ }
+
+ case 'Y': { /* PyByteArray object */
+ PyObject **p = va_arg(*p_va, PyObject **);
+ if (PyByteArray_Check(arg))
+ *p = arg;
+ else
+ return converterr("bytearray", arg, msgbuf, bufsize);
+ break;
+ }
+
+ case 'U': { /* PyUnicode object */
+ PyObject **p = va_arg(*p_va, PyObject **);
+ if (PyUnicode_Check(arg)) {
+ if (PyUnicode_READY(arg) == -1)
+ RETURN_ERR_OCCURRED;
+ *p = arg;
+ }
+ else
+ return converterr("str", arg, msgbuf, bufsize);
+ break;
+ }
+
+ case 'O': { /* object */
+ PyTypeObject *type;
+ PyObject **p;
+ if (*format == '!') {
+ type = va_arg(*p_va, PyTypeObject*);
+ p = va_arg(*p_va, PyObject **);
+ format++;
+ if (PyType_IsSubtype(Py_TYPE(arg), type))
+ *p = arg;
+ else
+ return converterr(type->tp_name, arg, msgbuf, bufsize);
+
+ }
+ else if (*format == '&') {
+ typedef int (*converter)(PyObject *, void *);
+ converter convert = va_arg(*p_va, converter);
+ void *addr = va_arg(*p_va, void *);
+ int res;
+ format++;
+ if (! (res = (*convert)(arg, addr)))
+ return converterr("(unspecified)",
+ arg, msgbuf, bufsize);
+ if (res == Py_CLEANUP_SUPPORTED &&
+ addcleanup(addr, freelist, convert) == -1)
+ return converterr("(cleanup problem)",
+ arg, msgbuf, bufsize);
+ }
+ else {
+ p = va_arg(*p_va, PyObject **);
+ *p = arg;
+ }
+ break;
+ }
+
+
+ case 'w': { /* "w*": memory buffer, read-write access */
+ void **p = va_arg(*p_va, void **);
+
+ if (*format != '*')
+ return converterr(
+ "(invalid use of 'w' format character)",
+ arg, msgbuf, bufsize);
+ format++;
+
+ /* Caller is interested in Py_buffer, and the object
+ supports it directly. */
+ if (PyObject_GetBuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {
+ PyErr_Clear();
+ return converterr("read-write bytes-like object",
+ arg, msgbuf, bufsize);
+ }
+ if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C')) {
+ PyBuffer_Release((Py_buffer*)p);
+ return converterr("contiguous buffer", arg, msgbuf, bufsize);
+ }
+ if (addcleanup(p, freelist, cleanup_buffer)) {
+ return converterr(
+ "(cleanup problem)",
+ arg, msgbuf, bufsize);
+ }
+ break;
+ }
+
+ default:
+ return converterr("(impossible<bad format char>)", arg, msgbuf, bufsize);
+
+ }
+
+ *p_format = format;
+ return NULL;
+
+#undef FETCH_SIZE
+#undef STORE_SIZE
+#undef BUFFER_LEN
+#undef RETURN_ERR_OCCURRED
+}
+
+static Py_ssize_t
+convertbuffer(PyObject *arg, const void **p, const char **errmsg)
+{
+ PyBufferProcs *pb = Py_TYPE(arg)->tp_as_buffer;
+ Py_ssize_t count;
+ Py_buffer view;
+
+ *errmsg = NULL;
+ *p = NULL;
+ if (pb != NULL && pb->bf_releasebuffer != NULL) {
+ *errmsg = "read-only bytes-like object";
+ return -1;
+ }
+
+ if (getbuffer(arg, &view, errmsg) < 0)
+ return -1;
+ count = view.len;
+ *p = view.buf;
+ PyBuffer_Release(&view);
+ return count;
+}
+
+static int
+getbuffer(PyObject *arg, Py_buffer *view, const char **errmsg)
+{
+ if (PyObject_GetBuffer(arg, view, PyBUF_SIMPLE) != 0) {
+ *errmsg = "bytes-like object";
+ return -1;
+ }
+ if (!PyBuffer_IsContiguous(view, 'C')) {
+ PyBuffer_Release(view);
+ *errmsg = "contiguous buffer";
+ return -1;
+ }
+ return 0;
+}
+
+/* Support for keyword arguments donated by
+ Geoff Philbrick <[email protected]> */
+
+/* Return false (0) for error, else true. */
+int
+PyArg_ParseTupleAndKeywords(PyObject *args,
+ PyObject *keywords,
+ const char *format,
+ char **kwlist, ...)
+{
+ int retval;
+ va_list va;
+
+ if ((args == NULL || !PyTuple_Check(args)) ||
+ (keywords != NULL && !PyDict_Check(keywords)) ||
+ format == NULL ||
+ kwlist == NULL)
+ {
+ PyErr_BadInternalCall();
+ return 0;
+ }
+
+ va_start(va, kwlist);
+ retval = vgetargskeywords(args, keywords, format, kwlist, &va, 0);
+ va_end(va);
+ return retval;
+}
+
+PyAPI_FUNC(int)
+_PyArg_ParseTupleAndKeywords_SizeT(PyObject *args,
+ PyObject *keywords,
+ const char *format,
+ char **kwlist, ...)
+{
+ int retval;
+ va_list va;
+
+ if ((args == NULL || !PyTuple_Check(args)) ||
+ (keywords != NULL && !PyDict_Check(keywords)) ||
+ format == NULL ||
+ kwlist == NULL)
+ {
+ PyErr_BadInternalCall();
+ return 0;
+ }
+
+ va_start(va, kwlist);
+ retval = vgetargskeywords(args, keywords, format,
+ kwlist, &va, FLAG_SIZE_T);
+ va_end(va);
+ return retval;
+}
+
+
+int
+PyArg_VaParseTupleAndKeywords(PyObject *args,
+ PyObject *keywords,
+ const char *format,
+ char **kwlist, va_list va)
+{
+ int retval;
+ va_list lva;
+
+ if ((args == NULL || !PyTuple_Check(args)) ||
+ (keywords != NULL && !PyDict_Check(keywords)) ||
+ format == NULL ||
+ kwlist == NULL)
+ {
+ PyErr_BadInternalCall();
+ return 0;
+ }
+
+ va_copy(lva, va);
+
+ retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0);
+ va_end(lva);
+ return retval;
+}
+
+PyAPI_FUNC(int)
+_PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args,
+ PyObject *keywords,
+ const char *format,
+ char **kwlist, va_list va)
+{
+ int retval;
+ va_list lva;
+
+ if ((args == NULL || !PyTuple_Check(args)) ||
+ (keywords != NULL && !PyDict_Check(keywords)) ||
+ format == NULL ||
+ kwlist == NULL)
+ {
+ PyErr_BadInternalCall();
+ return 0;
+ }
+
+ va_copy(lva, va);
+
+ retval = vgetargskeywords(args, keywords, format,
+ kwlist, &lva, FLAG_SIZE_T);
+ va_end(lva);
+ return retval;
+}
+
+PyAPI_FUNC(int)
+_PyArg_ParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords,
+ struct _PyArg_Parser *parser, ...)
+{
+ int retval;
+ va_list va;
+
+ va_start(va, parser);
+ retval = vgetargskeywordsfast(args, keywords, parser, &va, 0);
+ va_end(va);
+ return retval;
+}
+
+PyAPI_FUNC(int)
+_PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords,
+ struct _PyArg_Parser *parser, ...)
+{
+ int retval;
+ va_list va;
+
+ va_start(va, parser);
+ retval = vgetargskeywordsfast(args, keywords, parser, &va, FLAG_SIZE_T);
+ va_end(va);
+ return retval;
+}
+
+PyAPI_FUNC(int)
+_PyArg_ParseStackAndKeywords(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames,
+ struct _PyArg_Parser *parser, ...)
+{
+ int retval;
+ va_list va;
+
+ va_start(va, parser);
+ retval = vgetargskeywordsfast_impl(args, nargs, NULL, kwnames, parser, &va, 0);
+ va_end(va);
+ return retval;
+}
+
+PyAPI_FUNC(int)
+_PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames,
+ struct _PyArg_Parser *parser, ...)
+{
+ int retval;
+ va_list va;
+
+ va_start(va, parser);
+ retval = vgetargskeywordsfast_impl(args, nargs, NULL, kwnames, parser, &va, FLAG_SIZE_T);
+ va_end(va);
+ return retval;
+}
+
+
+PyAPI_FUNC(int)
+_PyArg_VaParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords,
+ struct _PyArg_Parser *parser, va_list va)
+{
+ int retval;
+ va_list lva;
+
+ va_copy(lva, va);
+
+ retval = vgetargskeywordsfast(args, keywords, parser, &lva, 0);
+ va_end(lva);
+ return retval;
+}
+
+PyAPI_FUNC(int)
+_PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords,
+ struct _PyArg_Parser *parser, va_list va)
+{
+ int retval;
+ va_list lva;
+
+ va_copy(lva, va);
+
+ retval = vgetargskeywordsfast(args, keywords, parser, &lva, FLAG_SIZE_T);
+ va_end(lva);
+ return retval;
+}
+
+int
+PyArg_ValidateKeywordArguments(PyObject *kwargs)
+{
+ if (!PyDict_Check(kwargs)) {
+ PyErr_BadInternalCall();
+ return 0;
+ }
+ if (!_PyDict_HasOnlyStringKeys(kwargs)) {
+ PyErr_SetString(PyExc_TypeError,
+ "keywords must be strings");
+ return 0;
+ }
+ return 1;
+}
+
+#define IS_END_OF_FORMAT(c) (c == '\0' || c == ';' || c == ':')
+
+static int
+vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
+ char **kwlist, va_list *p_va, int flags)
+{
+ char msgbuf[512];
+ int levels[32];
+ const char *fname, *msg, *custom_msg;
+ int min = INT_MAX;
+ int max = INT_MAX;
+ int i, pos, len;
+ int skip = 0;
+ Py_ssize_t nargs, nkwargs;
+ PyObject *current_arg;
+ freelistentry_t static_entries[STATIC_FREELIST_ENTRIES];
+ freelist_t freelist;
+
+ freelist.entries = static_entries;
+ freelist.first_available = 0;
+ freelist.entries_malloced = 0;
+
+ assert(args != NULL && PyTuple_Check(args));
+ assert(kwargs == NULL || PyDict_Check(kwargs));
+ assert(format != NULL);
+ assert(kwlist != NULL);
+ assert(p_va != NULL);
+
+ /* grab the function name or custom error msg first (mutually exclusive) */
+ fname = strchr(format, ':');
+ if (fname) {
+ fname++;
+ custom_msg = NULL;
+ }
+ else {
+ custom_msg = strchr(format,';');
+ if (custom_msg)
+ custom_msg++;
+ }
+
+ /* scan kwlist and count the number of positional-only parameters */
+ for (pos = 0; kwlist[pos] && !*kwlist[pos]; pos++) {
+ }
+ /* scan kwlist and get greatest possible nbr of args */
+ for (len = pos; kwlist[len]; len++) {
+ if (!*kwlist[len]) {
+ PyErr_SetString(PyExc_SystemError,
+ "Empty keyword parameter name");
+ return cleanreturn(0, &freelist);
+ }
+ }
+
+ if (len > STATIC_FREELIST_ENTRIES) {
+ freelist.entries = PyMem_NEW(freelistentry_t, len);
+ if (freelist.entries == NULL) {
+ PyErr_NoMemory();
+ return 0;
+ }
+ freelist.entries_malloced = 1;
+ }
+
+ nargs = PyTuple_GET_SIZE(args);
+ nkwargs = (kwargs == NULL) ? 0 : PyDict_GET_SIZE(kwargs);
+ if (nargs + nkwargs > len) {
+ /* Adding "keyword" (when nargs == 0) prevents producing wrong error
+ messages in some special cases (see bpo-31229). */
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%s takes at most %d %sargument%s (%zd given)",
+ (fname == NULL) ? "function" : fname,
+ (fname == NULL) ? "" : "()",
+ len,
+ (nargs == 0) ? "keyword " : "",
+ (len == 1) ? "" : "s",
+ nargs + nkwargs);
+ return cleanreturn(0, &freelist);
+ }
+
+ /* convert tuple args and keyword args in same loop, using kwlist to drive process */
+ for (i = 0; i < len; i++) {
+ if (*format == '|') {
+ if (min != INT_MAX) {
+ PyErr_SetString(PyExc_SystemError,
+ "Invalid format string (| specified twice)");
+ return cleanreturn(0, &freelist);
+ }
+
+ min = i;
+ format++;
+
+ if (max != INT_MAX) {
+ PyErr_SetString(PyExc_SystemError,
+ "Invalid format string ($ before |)");
+ return cleanreturn(0, &freelist);
+ }
+ }
+ if (*format == '$') {
+ if (max != INT_MAX) {
+ PyErr_SetString(PyExc_SystemError,
+ "Invalid format string ($ specified twice)");
+ return cleanreturn(0, &freelist);
+ }
+
+ max = i;
+ format++;
+
+ if (max < pos) {
+ PyErr_SetString(PyExc_SystemError,
+ "Empty parameter name after $");
+ return cleanreturn(0, &freelist);
+ }
+ if (skip) {
+ /* Now we know the minimal and the maximal numbers of
+ * positional arguments and can raise an exception with
+ * informative message (see below). */
+ break;
+ }
+ if (max < nargs) {
+ if (max == 0) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%s takes no positional arguments",
+ (fname == NULL) ? "function" : fname,
+ (fname == NULL) ? "" : "()");
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%s takes %s %d positional argument%s"
+ " (%zd given)",
+ (fname == NULL) ? "function" : fname,
+ (fname == NULL) ? "" : "()",
+ (min != INT_MAX) ? "at most" : "exactly",
+ max,
+ max == 1 ? "" : "s",
+ nargs);
+ }
+ return cleanreturn(0, &freelist);
+ }
+ }
+ if (IS_END_OF_FORMAT(*format)) {
+ PyErr_Format(PyExc_SystemError,
+ "More keyword list entries (%d) than "
+ "format specifiers (%d)", len, i);
+ return cleanreturn(0, &freelist);
+ }
+ if (!skip) {
+ if (i < nargs) {
+ current_arg = PyTuple_GET_ITEM(args, i);
+ }
+ else if (nkwargs && i >= pos) {
+ current_arg = _PyDict_GetItemStringWithError(kwargs, kwlist[i]);
+ if (current_arg) {
+ --nkwargs;
+ }
+ else if (PyErr_Occurred()) {
+ return cleanreturn(0, &freelist);
+ }
+ }
+ else {
+ current_arg = NULL;
+ }
+
+ if (current_arg) {
+ msg = convertitem(current_arg, &format, p_va, flags,
+ levels, msgbuf, sizeof(msgbuf), &freelist);
+ if (msg) {
+ seterror(i+1, msg, levels, fname, custom_msg);
+ return cleanreturn(0, &freelist);
+ }
+ continue;
+ }
+
+ if (i < min) {
+ if (i < pos) {
+ assert (min == INT_MAX);
+ assert (max == INT_MAX);
+ skip = 1;
+ /* At that moment we still don't know the minimal and
+ * the maximal numbers of positional arguments. Raising
+ * an exception is deferred until we encounter | and $
+ * or the end of the format. */
+ }
+ else {
+ PyErr_Format(PyExc_TypeError, "%.200s%s missing required "
+ "argument '%s' (pos %d)",
+ (fname == NULL) ? "function" : fname,
+ (fname == NULL) ? "" : "()",
+ kwlist[i], i+1);
+ return cleanreturn(0, &freelist);
+ }
+ }
+ /* current code reports success when all required args
+ * fulfilled and no keyword args left, with no further
+ * validation. XXX Maybe skip this in debug build ?
+ */
+ if (!nkwargs && !skip) {
+ return cleanreturn(1, &freelist);
+ }
+ }
+
+ /* We are into optional args, skip through to any remaining
+ * keyword args */
+ msg = skipitem(&format, p_va, flags);
+ if (msg) {
+ PyErr_Format(PyExc_SystemError, "%s: '%s'", msg,
+ format);
+ return cleanreturn(0, &freelist);
+ }
+ }
+
+ if (skip) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%s takes %s %d positional argument%s"
+ " (%zd given)",
+ (fname == NULL) ? "function" : fname,
+ (fname == NULL) ? "" : "()",
+ (Py_MIN(pos, min) < i) ? "at least" : "exactly",
+ Py_MIN(pos, min),
+ Py_MIN(pos, min) == 1 ? "" : "s",
+ nargs);
+ return cleanreturn(0, &freelist);
+ }
+
+ if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) {
+ PyErr_Format(PyExc_SystemError,
+ "more argument specifiers than keyword list entries "
+ "(remaining format:'%s')", format);
+ return cleanreturn(0, &freelist);
+ }
+
+ if (nkwargs > 0) {
+ PyObject *key;
+ Py_ssize_t j;
+ /* make sure there are no arguments given by name and position */
+ for (i = pos; i < nargs; i++) {
+ current_arg = _PyDict_GetItemStringWithError(kwargs, kwlist[i]);
+ if (current_arg) {
+ /* arg present in tuple and in dict */
+ PyErr_Format(PyExc_TypeError,
+ "argument for %.200s%s given by name ('%s') "
+ "and position (%d)",
+ (fname == NULL) ? "function" : fname,
+ (fname == NULL) ? "" : "()",
+ kwlist[i], i+1);
+ return cleanreturn(0, &freelist);
+ }
+ else if (PyErr_Occurred()) {
+ return cleanreturn(0, &freelist);
+ }
+ }
+ /* make sure there are no extraneous keyword arguments */
+ j = 0;
+ while (PyDict_Next(kwargs, &j, &key, NULL)) {
+ int match = 0;
+ if (!PyUnicode_Check(key)) {
+ PyErr_SetString(PyExc_TypeError,
+ "keywords must be strings");
+ return cleanreturn(0, &freelist);
+ }
+ for (i = pos; i < len; i++) {
+ if (_PyUnicode_EqualToASCIIString(key, kwlist[i])) {
+ match = 1;
+ break;
+ }
+ }
+ if (!match) {
+ PyErr_Format(PyExc_TypeError,
+ "'%U' is an invalid keyword "
+ "argument for %.200s%s",
+ key,
+ (fname == NULL) ? "this function" : fname,
+ (fname == NULL) ? "" : "()");
+ return cleanreturn(0, &freelist);
+ }
+ }
+ }
+
+ return cleanreturn(1, &freelist);
+}
+
+
+/* List of static parsers. */
+static struct _PyArg_Parser *static_arg_parsers = NULL;
+
+static int
+parser_init(struct _PyArg_Parser *parser)
+{
+ const char * const *keywords;
+ const char *format, *msg;
+ int i, len, min, max, nkw;
+ PyObject *kwtuple;
+
+ assert(parser->keywords != NULL);
+ if (parser->kwtuple != NULL) {
+ return 1;
+ }
+
+ keywords = parser->keywords;
+ /* scan keywords and count the number of positional-only parameters */
+ for (i = 0; keywords[i] && !*keywords[i]; i++) {
+ }
+ parser->pos = i;
+ /* scan keywords and get greatest possible nbr of args */
+ for (; keywords[i]; i++) {
+ if (!*keywords[i]) {
+ PyErr_SetString(PyExc_SystemError,
+ "Empty keyword parameter name");
+ return 0;
+ }
+ }
+ len = i;
+
+ format = parser->format;
+ if (format) {
+ /* grab the function name or custom error msg first (mutually exclusive) */
+ parser->fname = strchr(parser->format, ':');
+ if (parser->fname) {
+ parser->fname++;
+ parser->custom_msg = NULL;
+ }
+ else {
+ parser->custom_msg = strchr(parser->format,';');
+ if (parser->custom_msg)
+ parser->custom_msg++;
+ }
+
+ min = max = INT_MAX;
+ for (i = 0; i < len; i++) {
+ if (*format == '|') {
+ if (min != INT_MAX) {
+ PyErr_SetString(PyExc_SystemError,
+ "Invalid format string (| specified twice)");
+ return 0;
+ }
+ if (max != INT_MAX) {
+ PyErr_SetString(PyExc_SystemError,
+ "Invalid format string ($ before |)");
+ return 0;
+ }
+ min = i;
+ format++;
+ }
+ if (*format == '$') {
+ if (max != INT_MAX) {
+ PyErr_SetString(PyExc_SystemError,
+ "Invalid format string ($ specified twice)");
+ return 0;
+ }
+ if (i < parser->pos) {
+ PyErr_SetString(PyExc_SystemError,
+ "Empty parameter name after $");
+ return 0;
+ }
+ max = i;
+ format++;
+ }
+ if (IS_END_OF_FORMAT(*format)) {
+ PyErr_Format(PyExc_SystemError,
+ "More keyword list entries (%d) than "
+ "format specifiers (%d)", len, i);
+ return 0;
+ }
+
+ msg = skipitem(&format, NULL, 0);
+ if (msg) {
+ PyErr_Format(PyExc_SystemError, "%s: '%s'", msg,
+ format);
+ return 0;
+ }
+ }
+ parser->min = Py_MIN(min, len);
+ parser->max = Py_MIN(max, len);
+
+ if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) {
+ PyErr_Format(PyExc_SystemError,
+ "more argument specifiers than keyword list entries "
+ "(remaining format:'%s')", format);
+ return 0;
+ }
+ }
+
+ nkw = len - parser->pos;
+ kwtuple = PyTuple_New(nkw);
+ if (kwtuple == NULL) {
+ return 0;
+ }
+ keywords = parser->keywords + parser->pos;
+ for (i = 0; i < nkw; i++) {
+ PyObject *str = PyUnicode_FromString(keywords[i]);
+ if (str == NULL) {
+ Py_DECREF(kwtuple);
+ return 0;
+ }
+ PyUnicode_InternInPlace(&str);
+ PyTuple_SET_ITEM(kwtuple, i, str);
+ }
+ parser->kwtuple = kwtuple;
+
+ assert(parser->next == NULL);
+ parser->next = static_arg_parsers;
+ static_arg_parsers = parser;
+ return 1;
+}
+
+static void
+parser_clear(struct _PyArg_Parser *parser)
+{
+ Py_CLEAR(parser->kwtuple);
+}
+
+static PyObject*
+find_keyword(PyObject *kwnames, PyObject *const *kwstack, PyObject *key)
+{
+ Py_ssize_t i, nkwargs;
+
+ nkwargs = PyTuple_GET_SIZE(kwnames);
+ for (i = 0; i < nkwargs; i++) {
+ PyObject *kwname = PyTuple_GET_ITEM(kwnames, i);
+
+ /* kwname == key will normally find a match in since keyword keys
+ should be interned strings; if not retry below in a new loop. */
+ if (kwname == key) {
+ return kwstack[i];
+ }
+ }
+
+ for (i = 0; i < nkwargs; i++) {
+ PyObject *kwname = PyTuple_GET_ITEM(kwnames, i);
+ assert(PyUnicode_Check(kwname));
+ if (_PyUnicode_EQ(kwname, key)) {
+ return kwstack[i];
+ }
+ }
+ return NULL;
+}
+
+static int
+vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs,
+ PyObject *kwargs, PyObject *kwnames,
+ struct _PyArg_Parser *parser,
+ va_list *p_va, int flags)
+{
+ PyObject *kwtuple;
+ char msgbuf[512];
+ int levels[32];
+ const char *format;
+ const char *msg;
+ PyObject *keyword;
+ int i, pos, len;
+ Py_ssize_t nkwargs;
+ PyObject *current_arg;
+ 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(kwargs == NULL || PyDict_Check(kwargs));
+ assert(kwargs == NULL || kwnames == NULL);
+ assert(p_va != NULL);
+
+ if (parser == NULL) {
+ PyErr_BadInternalCall();
+ return 0;
+ }
+
+ if (kwnames != NULL && !PyTuple_Check(kwnames)) {
+ PyErr_BadInternalCall();
+ return 0;
+ }
+
+ if (!parser_init(parser)) {
+ return 0;
+ }
+
+ kwtuple = parser->kwtuple;
+ pos = parser->pos;
+ len = pos + (int)PyTuple_GET_SIZE(kwtuple);
+
+ if (len > STATIC_FREELIST_ENTRIES) {
+ freelist.entries = PyMem_NEW(freelistentry_t, len);
+ if (freelist.entries == NULL) {
+ PyErr_NoMemory();
+ return 0;
+ }
+ freelist.entries_malloced = 1;
+ }
+
+ 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). */
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%s takes at most %d %sargument%s (%zd given)",
+ (parser->fname == NULL) ? "function" : parser->fname,
+ (parser->fname == NULL) ? "" : "()",
+ len,
+ (nargs == 0) ? "keyword " : "",
+ (len == 1) ? "" : "s",
+ nargs + nkwargs);
+ return cleanreturn(0, &freelist);
+ }
+ if (parser->max < nargs) {
+ if (parser->max == 0) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%s takes no positional arguments",
+ (parser->fname == NULL) ? "function" : parser->fname,
+ (parser->fname == NULL) ? "" : "()");
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%s takes %s %d positional argument%s (%zd given)",
+ (parser->fname == NULL) ? "function" : parser->fname,
+ (parser->fname == NULL) ? "" : "()",
+ (parser->min < parser->max) ? "at most" : "exactly",
+ parser->max,
+ parser->max == 1 ? "" : "s",
+ nargs);
+ }
+ return cleanreturn(0, &freelist);
+ }
+
+ format = parser->format;
+ /* convert tuple args and keyword args in same loop, using kwtuple to drive process */
+ for (i = 0; i < len; i++) {
+ if (*format == '|') {
+ format++;
+ }
+ if (*format == '$') {
+ format++;
+ }
+ assert(!IS_END_OF_FORMAT(*format));
+
+ if (i < nargs) {
+ current_arg = args[i];
+ }
+ else if (nkwargs && i >= pos) {
+ keyword = PyTuple_GET_ITEM(kwtuple, i - pos);
+ if (kwargs != NULL) {
+ current_arg = PyDict_GetItemWithError(kwargs, keyword);
+ if (!current_arg && PyErr_Occurred()) {
+ return cleanreturn(0, &freelist);
+ }
+ }
+ else {
+ current_arg = find_keyword(kwnames, kwstack, keyword);
+ }
+ if (current_arg) {
+ --nkwargs;
+ }
+ }
+ else {
+ current_arg = NULL;
+ }
+
+ if (current_arg) {
+ msg = convertitem(current_arg, &format, p_va, flags,
+ levels, msgbuf, sizeof(msgbuf), &freelist);
+ if (msg) {
+ seterror(i+1, msg, levels, parser->fname, parser->custom_msg);
+ return cleanreturn(0, &freelist);
+ }
+ continue;
+ }
+
+ if (i < parser->min) {
+ /* Less arguments than required */
+ if (i < pos) {
+ Py_ssize_t min = Py_MIN(pos, parser->min);
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%s takes %s %d positional argument%s"
+ " (%zd given)",
+ (parser->fname == NULL) ? "function" : parser->fname,
+ (parser->fname == NULL) ? "" : "()",
+ min < parser->max ? "at least" : "exactly",
+ min,
+ min == 1 ? "" : "s",
+ nargs);
+ }
+ else {
+ keyword = PyTuple_GET_ITEM(kwtuple, i - pos);
+ PyErr_Format(PyExc_TypeError, "%.200s%s missing required "
+ "argument '%U' (pos %d)",
+ (parser->fname == NULL) ? "function" : parser->fname,
+ (parser->fname == NULL) ? "" : "()",
+ keyword, i+1);
+ }
+ return cleanreturn(0, &freelist);
+ }
+ /* current code reports success when all required args
+ * fulfilled and no keyword args left, with no further
+ * validation. XXX Maybe skip this in debug build ?
+ */
+ if (!nkwargs) {
+ return cleanreturn(1, &freelist);
+ }
+
+ /* We are into optional args, skip through to any remaining
+ * keyword args */
+ msg = skipitem(&format, p_va, flags);
+ assert(msg == NULL);
+ }
+
+ assert(IS_END_OF_FORMAT(*format) || (*format == '|') || (*format == '$'));
+
+ if (nkwargs > 0) {
+ Py_ssize_t j;
+ /* make sure there are no arguments given by name and position */
+ for (i = pos; i < nargs; i++) {
+ keyword = PyTuple_GET_ITEM(kwtuple, i - pos);
+ if (kwargs != NULL) {
+ current_arg = PyDict_GetItemWithError(kwargs, keyword);
+ if (!current_arg && PyErr_Occurred()) {
+ return cleanreturn(0, &freelist);
+ }
+ }
+ else {
+ current_arg = find_keyword(kwnames, kwstack, keyword);
+ }
+ if (current_arg) {
+ /* arg present in tuple and in dict */
+ PyErr_Format(PyExc_TypeError,
+ "argument for %.200s%s given by name ('%U') "
+ "and position (%d)",
+ (parser->fname == NULL) ? "function" : parser->fname,
+ (parser->fname == NULL) ? "" : "()",
+ keyword, i+1);
+ return cleanreturn(0, &freelist);
+ }
+ }
+ /* make sure there are no extraneous keyword arguments */
+ j = 0;
+ while (1) {
+ int match;
+ if (kwargs != NULL) {
+ if (!PyDict_Next(kwargs, &j, &keyword, NULL))
+ break;
+ }
+ else {
+ if (j >= PyTuple_GET_SIZE(kwnames))
+ break;
+ keyword = PyTuple_GET_ITEM(kwnames, j);
+ j++;
+ }
+
+ match = PySequence_Contains(kwtuple, keyword);
+ if (match <= 0) {
+ if (!match) {
+ PyErr_Format(PyExc_TypeError,
+ "'%S' is an invalid keyword "
+ "argument for %.200s%s",
+ keyword,
+ (parser->fname == NULL) ? "this function" : parser->fname,
+ (parser->fname == NULL) ? "" : "()");
+ }
+ return cleanreturn(0, &freelist);
+ }
+ }
+ }
+
+ return cleanreturn(1, &freelist);
+}
+
+static int
+vgetargskeywordsfast(PyObject *args, PyObject *keywords,
+ struct _PyArg_Parser *parser, va_list *p_va, int flags)
+{
+ PyObject **stack;
+ Py_ssize_t nargs;
+
+ if (args == NULL
+ || !PyTuple_Check(args)
+ || (keywords != NULL && !PyDict_Check(keywords)))
+ {
+ PyErr_BadInternalCall();
+ return 0;
+ }
+
+ stack = _PyTuple_ITEMS(args);
+ nargs = PyTuple_GET_SIZE(args);
+ return vgetargskeywordsfast_impl(stack, nargs, keywords, NULL,
+ parser, p_va, flags);
+}
+
+
+#undef _PyArg_UnpackKeywords
+
+PyObject * const *
+_PyArg_UnpackKeywords(PyObject *const *args, Py_ssize_t nargs,
+ PyObject *kwargs, PyObject *kwnames,
+ struct _PyArg_Parser *parser,
+ int minpos, int maxpos, int minkw,
+ PyObject **buf)
+{
+ PyObject *kwtuple;
+ PyObject *keyword;
+ int i, posonly, minposonly, maxargs;
+ int reqlimit = minkw ? maxpos + minkw : minpos;
+ Py_ssize_t nkwargs;
+ PyObject *current_arg;
+ PyObject * const *kwstack = NULL;
+
+ assert(kwargs == NULL || PyDict_Check(kwargs));
+ assert(kwargs == NULL || kwnames == NULL);
+
+ if (parser == NULL) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+
+ if (kwnames != NULL && !PyTuple_Check(kwnames)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+
+ if (args == NULL && nargs == 0) {
+ args = buf;
+ }
+
+ if (!parser_init(parser)) {
+ return NULL;
+ }
+
+ kwtuple = parser->kwtuple;
+ posonly = parser->pos;
+ minposonly = Py_MIN(posonly, minpos);
+ maxargs = posonly + (int)PyTuple_GET_SIZE(kwtuple);
+
+ if (kwargs != NULL) {
+ nkwargs = PyDict_GET_SIZE(kwargs);
+ }
+ else if (kwnames != NULL) {
+ nkwargs = PyTuple_GET_SIZE(kwnames);
+ kwstack = args + nargs;
+ }
+ else {
+ nkwargs = 0;
+ }
+ if (nkwargs == 0 && minkw == 0 && minpos <= nargs && nargs <= maxpos) {
+ /* Fast path. */
+ return args;
+ }
+ if (nargs + nkwargs > maxargs) {
+ /* Adding "keyword" (when nargs == 0) prevents producing wrong error
+ messages in some special cases (see bpo-31229). */
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%s takes at most %d %sargument%s (%zd given)",
+ (parser->fname == NULL) ? "function" : parser->fname,
+ (parser->fname == NULL) ? "" : "()",
+ maxargs,
+ (nargs == 0) ? "keyword " : "",
+ (maxargs == 1) ? "" : "s",
+ nargs + nkwargs);
+ return NULL;
+ }
+ if (nargs > maxpos) {
+ if (maxpos == 0) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%s takes no positional arguments",
+ (parser->fname == NULL) ? "function" : parser->fname,
+ (parser->fname == NULL) ? "" : "()");
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%s takes %s %d positional argument%s (%zd given)",
+ (parser->fname == NULL) ? "function" : parser->fname,
+ (parser->fname == NULL) ? "" : "()",
+ (minpos < maxpos) ? "at most" : "exactly",
+ maxpos,
+ (maxpos == 1) ? "" : "s",
+ nargs);
+ }
+ return NULL;
+ }
+ if (nargs < minposonly) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%s takes %s %d positional argument%s"
+ " (%zd given)",
+ (parser->fname == NULL) ? "function" : parser->fname,
+ (parser->fname == NULL) ? "" : "()",
+ minposonly < maxpos ? "at least" : "exactly",
+ minposonly,
+ minposonly == 1 ? "" : "s",
+ nargs);
+ return NULL;
+ }
+
+ /* copy tuple args */
+ for (i = 0; i < nargs; i++) {
+ buf[i] = args[i];
+ }
+
+ /* copy keyword args using kwtuple to drive process */
+ for (i = Py_MAX((int)nargs, posonly); i < maxargs; i++) {
+ if (nkwargs) {
+ keyword = PyTuple_GET_ITEM(kwtuple, i - posonly);
+ if (kwargs != NULL) {
+ current_arg = PyDict_GetItemWithError(kwargs, keyword);
+ if (!current_arg && PyErr_Occurred()) {
+ return NULL;
+ }
+ }
+ else {
+ current_arg = find_keyword(kwnames, kwstack, keyword);
+ }
+ }
+ else if (i >= reqlimit) {
+ break;
+ }
+ else {
+ current_arg = NULL;
+ }
+
+ buf[i] = current_arg;
+
+ if (current_arg) {
+ --nkwargs;
+ }
+ else if (i < minpos || (maxpos <= i && i < reqlimit)) {
+ /* Less arguments than required */
+ keyword = PyTuple_GET_ITEM(kwtuple, i - posonly);
+ PyErr_Format(PyExc_TypeError, "%.200s%s missing required "
+ "argument '%U' (pos %d)",
+ (parser->fname == NULL) ? "function" : parser->fname,
+ (parser->fname == NULL) ? "" : "()",
+ keyword, i+1);
+ return NULL;
+ }
+ }
+
+ if (nkwargs > 0) {
+ Py_ssize_t j;
+ /* make sure there are no arguments given by name and position */
+ for (i = posonly; i < nargs; i++) {
+ keyword = PyTuple_GET_ITEM(kwtuple, i - posonly);
+ if (kwargs != NULL) {
+ current_arg = PyDict_GetItemWithError(kwargs, keyword);
+ if (!current_arg && PyErr_Occurred()) {
+ return NULL;
+ }
+ }
+ else {
+ current_arg = find_keyword(kwnames, kwstack, keyword);
+ }
+ if (current_arg) {
+ /* arg present in tuple and in dict */
+ PyErr_Format(PyExc_TypeError,
+ "argument for %.200s%s given by name ('%U') "
+ "and position (%d)",
+ (parser->fname == NULL) ? "function" : parser->fname,
+ (parser->fname == NULL) ? "" : "()",
+ keyword, i+1);
+ return NULL;
+ }
+ }
+ /* make sure there are no extraneous keyword arguments */
+ j = 0;
+ while (1) {
+ int match;
+ if (kwargs != NULL) {
+ if (!PyDict_Next(kwargs, &j, &keyword, NULL))
+ break;
+ }
+ else {
+ if (j >= PyTuple_GET_SIZE(kwnames))
+ break;
+ keyword = PyTuple_GET_ITEM(kwnames, j);
+ j++;
+ }
+
+ match = PySequence_Contains(kwtuple, keyword);
+ if (match <= 0) {
+ if (!match) {
+ PyErr_Format(PyExc_TypeError,
+ "'%S' is an invalid keyword "
+ "argument for %.200s%s",
+ keyword,
+ (parser->fname == NULL) ? "this function" : parser->fname,
+ (parser->fname == NULL) ? "" : "()");
+ }
+ return NULL;
+ }
+ }
+ }
+
+ return buf;
+}
+
+
+static const char *
+skipitem(const char **p_format, va_list *p_va, int flags)
+{
+ const char *format = *p_format;
+ char c = *format++;
+
+ switch (c) {
+
+ /*
+ * codes that take a single data pointer as an argument
+ * (the type of the pointer is irrelevant)
+ */
+
+ case 'b': /* byte -- very short int */
+ case 'B': /* byte as bitfield */
+ case 'h': /* short int */
+ case 'H': /* short int as bitfield */
+ case 'i': /* int */
+ case 'I': /* int sized bitfield */
+ case 'l': /* long int */
+ case 'k': /* long int sized bitfield */
+ case 'L': /* long long */
+ case 'K': /* long long sized bitfield */
+ case 'n': /* Py_ssize_t */
+ case 'f': /* float */
+ case 'd': /* double */
+ case 'D': /* complex double */
+ case 'c': /* char */
+ case 'C': /* unicode char */
+ case 'p': /* boolean predicate */
+ case 'S': /* string object */
+ case 'Y': /* string object */
+ case 'U': /* unicode string object */
+ {
+ if (p_va != NULL) {
+ (void) va_arg(*p_va, void *);
+ }
+ break;
+ }
+
+ /* string codes */
+
+ case 'e': /* string with encoding */
+ {
+ if (p_va != NULL) {
+ (void) va_arg(*p_va, const char *);
+ }
+ if (!(*format == 's' || *format == 't'))
+ /* after 'e', only 's' and 't' is allowed */
+ goto err;
+ format++;
+ }
+ /* fall through */
+
+ case 's': /* string */
+ case 'z': /* string or None */
+ case 'y': /* bytes */
+ case 'u': /* unicode string */
+ case 'Z': /* unicode string or None */
+ case 'w': /* buffer, read-write */
+ {
+ if (p_va != NULL) {
+ (void) va_arg(*p_va, char **);
+ }
+ if (*format == '#') {
+ if (p_va != NULL) {
+ if (flags & FLAG_SIZE_T)
+ (void) va_arg(*p_va, Py_ssize_t *);
+ else {
+ if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) {
+ return NULL;
+ }
+ (void) va_arg(*p_va, int *);
+ }
+ }
+ format++;
+ } else if ((c == 's' || c == 'z' || c == 'y' || c == 'w')
+ && *format == '*')
+ {
+ format++;
+ }
+ break;
+ }
+
+ case 'O': /* object */
+ {
+ if (*format == '!') {
+ format++;
+ if (p_va != NULL) {
+ (void) va_arg(*p_va, PyTypeObject*);
+ (void) va_arg(*p_va, PyObject **);
+ }
+ }
+ else if (*format == '&') {
+ typedef int (*converter)(PyObject *, void *);
+ if (p_va != NULL) {
+ (void) va_arg(*p_va, converter);
+ (void) va_arg(*p_va, void *);
+ }
+ format++;
+ }
+ else {
+ if (p_va != NULL) {
+ (void) va_arg(*p_va, PyObject **);
+ }
+ }
+ break;
+ }
+
+ case '(': /* bypass tuple, not handled at all previously */
+ {
+ const char *msg;
+ for (;;) {
+ if (*format==')')
+ break;
+ if (IS_END_OF_FORMAT(*format))
+ return "Unmatched left paren in format "
+ "string";
+ msg = skipitem(&format, p_va, flags);
+ if (msg)
+ return msg;
+ }
+ format++;
+ break;
+ }
+
+ case ')':
+ return "Unmatched right paren in format string";
+
+ default:
+err:
+ return "impossible<bad format char>";
+
+ }
+
+ *p_format = format;
+ return NULL;
+}
+
+
+#undef _PyArg_CheckPositional
+
+int
+_PyArg_CheckPositional(const char *name, Py_ssize_t nargs,
+ Py_ssize_t min, Py_ssize_t max)
+{
+ assert(min >= 0);
+ assert(min <= max);
+
+ if (nargs < min) {
+ if (name != NULL)
+ PyErr_Format(
+ PyExc_TypeError,
+ "%.200s expected %s%zd argument%s, got %zd",
+ name, (min == max ? "" : "at least "), min, min == 1 ? "" : "s", nargs);
+ else
+ PyErr_Format(
+ PyExc_TypeError,
+ "unpacked tuple should have %s%zd element%s,"
+ " but has %zd",
+ (min == max ? "" : "at least "), min, min == 1 ? "" : "s", nargs);
+ return 0;
+ }
+
+ if (nargs == 0) {
+ return 1;
+ }
+
+ if (nargs > max) {
+ if (name != NULL)
+ PyErr_Format(
+ PyExc_TypeError,
+ "%.200s expected %s%zd argument%s, got %zd",
+ name, (min == max ? "" : "at most "), max, max == 1 ? "" : "s", nargs);
+ else
+ PyErr_Format(
+ PyExc_TypeError,
+ "unpacked tuple should have %s%zd element%s,"
+ " but has %zd",
+ (min == max ? "" : "at most "), max, max == 1 ? "" : "s", nargs);
+ return 0;
+ }
+
+ return 1;
+}
+
+static int
+unpack_stack(PyObject *const *args, Py_ssize_t nargs, const char *name,
+ Py_ssize_t min, Py_ssize_t max, va_list vargs)
+{
+ Py_ssize_t i;
+ PyObject **o;
+
+ if (!_PyArg_CheckPositional(name, nargs, min, max)) {
+ return 0;
+ }
+
+ for (i = 0; i < nargs; i++) {
+ o = va_arg(vargs, PyObject **);
+ *o = args[i];
+ }
+ return 1;
+}
+
+int
+PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...)
+{
+ PyObject **stack;
+ Py_ssize_t nargs;
+ int retval;
+ va_list vargs;
+
+ if (!PyTuple_Check(args)) {
+ PyErr_SetString(PyExc_SystemError,
+ "PyArg_UnpackTuple() argument list is not a tuple");
+ return 0;
+ }
+ stack = _PyTuple_ITEMS(args);
+ nargs = PyTuple_GET_SIZE(args);
+
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, max);
+#else
+ va_start(vargs);
+#endif
+ retval = unpack_stack(stack, nargs, name, min, max, vargs);
+ va_end(vargs);
+ return retval;
+}
+
+int
+_PyArg_UnpackStack(PyObject *const *args, Py_ssize_t nargs, const char *name,
+ Py_ssize_t min, Py_ssize_t max, ...)
+{
+ int retval;
+ va_list vargs;
+
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, max);
+#else
+ va_start(vargs);
+#endif
+ retval = unpack_stack(args, nargs, name, min, max, vargs);
+ va_end(vargs);
+ return retval;
+}
+
+
+#undef _PyArg_NoKeywords
+#undef _PyArg_NoKwnames
+#undef _PyArg_NoPositional
+
+/* For type constructors that don't take keyword args
+ *
+ * Sets a TypeError and returns 0 if the args/kwargs is
+ * not empty, returns 1 otherwise
+ */
+int
+_PyArg_NoKeywords(const char *funcname, PyObject *kwargs)
+{
+ if (kwargs == NULL) {
+ return 1;
+ }
+ if (!PyDict_CheckExact(kwargs)) {
+ PyErr_BadInternalCall();
+ return 0;
+ }
+ if (PyDict_GET_SIZE(kwargs) == 0) {
+ return 1;
+ }
+
+ PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
+ funcname);
+ return 0;
+}
+
+int
+_PyArg_NoPositional(const char *funcname, PyObject *args)
+{
+ if (args == NULL)
+ return 1;
+ if (!PyTuple_CheckExact(args)) {
+ PyErr_BadInternalCall();
+ return 0;
+ }
+ if (PyTuple_GET_SIZE(args) == 0)
+ return 1;
+
+ PyErr_Format(PyExc_TypeError, "%.200s() takes no positional arguments",
+ funcname);
+ return 0;
+}
+
+int
+_PyArg_NoKwnames(const char *funcname, PyObject *kwnames)
+{
+ if (kwnames == NULL) {
+ return 1;
+ }
+
+ assert(PyTuple_CheckExact(kwnames));
+
+ if (PyTuple_GET_SIZE(kwnames) == 0) {
+ return 1;
+ }
+
+ PyErr_Format(PyExc_TypeError, "%s() takes no keyword arguments", funcname);
+ return 0;
+}
+
+void
+_PyArg_Fini(void)
+{
+ struct _PyArg_Parser *tmp, *s = static_arg_parsers;
+ while (s) {
+ tmp = s->next;
+ s->next = NULL;
+ parser_clear(s);
+ s = tmp;
+ }
+ static_arg_parsers = NULL;
+}
+
+#ifdef __cplusplus
+};
+#endif
diff --git a/contrib/tools/python3/src/Python/getcompiler.c b/contrib/tools/python3/src/Python/getcompiler.c
new file mode 100644
index 00000000000..59c0dbf92ae
--- /dev/null
+++ b/contrib/tools/python3/src/Python/getcompiler.c
@@ -0,0 +1,27 @@
+
+/* Return the compiler identification, if possible. */
+
+#include "Python.h"
+
+#ifndef COMPILER
+
+// Note the __clang__ conditional has to come before the __GNUC__ one because
+// clang pretends to be GCC.
+#if defined(__clang__)
+#define COMPILER "\n[Clang " __clang_version__ "]"
+#elif defined(__GNUC__)
+#define COMPILER "\n[GCC " __VERSION__ "]"
+// Generic fallbacks.
+#elif defined(__cplusplus)
+#define COMPILER "[C++]"
+#else
+#define COMPILER "[C]"
+#endif
+
+#endif /* !COMPILER */
+
+const char *
+Py_GetCompiler(void)
+{
+ return COMPILER;
+}
diff --git a/contrib/tools/python3/src/Python/getcopyright.c b/contrib/tools/python3/src/Python/getcopyright.c
new file mode 100644
index 00000000000..88d1d053625
--- /dev/null
+++ b/contrib/tools/python3/src/Python/getcopyright.c
@@ -0,0 +1,23 @@
+/* Return the copyright string. This is updated manually. */
+
+#include "Python.h"
+
+static const char cprt[] =
+"\
+Copyright (c) 2001-2022 Python Software Foundation.\n\
+All Rights Reserved.\n\
+\n\
+Copyright (c) 2000 BeOpen.com.\n\
+All Rights Reserved.\n\
+\n\
+Copyright (c) 1995-2001 Corporation for National Research Initiatives.\n\
+All Rights Reserved.\n\
+\n\
+Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.\n\
+All Rights Reserved.";
+
+const char *
+Py_GetCopyright(void)
+{
+ return cprt;
+}
diff --git a/contrib/tools/python3/src/Python/getopt.c b/contrib/tools/python3/src/Python/getopt.c
new file mode 100644
index 00000000000..2e3891aae2d
--- /dev/null
+++ b/contrib/tools/python3/src/Python/getopt.c
@@ -0,0 +1,175 @@
+/*---------------------------------------------------------------------------*
+ * <RCS keywords>
+ *
+ * C++ Library
+ *
+ * Copyright 1992-1994, David Gottner
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice, this permission notice and
+ * the following disclaimer notice appear unmodified in all copies.
+ *
+ * I DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL I
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *---------------------------------------------------------------------------*/
+
+/* Modified to support --help and --version, as well as /? on Windows
+ * by Georg Brandl. */
+
+#include <Python.h>
+#include <stdio.h>
+#include <string.h>
+#include <wchar.h>
+#include "pycore_getopt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int _PyOS_opterr = 1; /* generate error messages */
+Py_ssize_t _PyOS_optind = 1; /* index into argv array */
+const wchar_t *_PyOS_optarg = NULL; /* optional argument */
+
+static const wchar_t *opt_ptr = L"";
+
+/* Python command line short and long options */
+
+#define SHORT_OPTS L"bBc:dEhiIJm:OqRsStuvVW:xX:?"
+
+static const _PyOS_LongOption longopts[] = {
+ {L"check-hash-based-pycs", 1, 0},
+ {NULL, 0, 0},
+};
+
+
+void _PyOS_ResetGetOpt(void)
+{
+ _PyOS_opterr = 1;
+ _PyOS_optind = 1;
+ _PyOS_optarg = NULL;
+ opt_ptr = L"";
+}
+
+int _PyOS_GetOpt(Py_ssize_t argc, wchar_t * const *argv, int *longindex)
+{
+ wchar_t *ptr;
+ wchar_t option;
+
+ if (*opt_ptr == '\0') {
+
+ if (_PyOS_optind >= argc)
+ return -1;
+#ifdef MS_WINDOWS
+ else if (wcscmp(argv[_PyOS_optind], L"/?") == 0) {
+ ++_PyOS_optind;
+ return 'h';
+ }
+#endif
+
+ else if (argv[_PyOS_optind][0] != L'-' ||
+ argv[_PyOS_optind][1] == L'\0' /* lone dash */ )
+ return -1;
+
+ else if (wcscmp(argv[_PyOS_optind], L"--") == 0) {
+ ++_PyOS_optind;
+ return -1;
+ }
+
+ else if (wcscmp(argv[_PyOS_optind], L"--help") == 0) {
+ ++_PyOS_optind;
+ return 'h';
+ }
+
+ else if (wcscmp(argv[_PyOS_optind], L"--version") == 0) {
+ ++_PyOS_optind;
+ return 'V';
+ }
+
+ opt_ptr = &argv[_PyOS_optind++][1];
+ }
+
+ if ((option = *opt_ptr++) == L'\0')
+ return -1;
+
+ if (option == L'-') {
+ // Parse long option.
+ if (*opt_ptr == L'\0') {
+ if (_PyOS_opterr) {
+ fprintf(stderr, "expected long option\n");
+ }
+ return -1;
+ }
+ *longindex = 0;
+ const _PyOS_LongOption *opt;
+ for (opt = &longopts[*longindex]; opt->name; opt = &longopts[++(*longindex)]) {
+ if (!wcscmp(opt->name, opt_ptr))
+ break;
+ }
+ if (!opt->name) {
+ if (_PyOS_opterr) {
+ fprintf(stderr, "unknown option %ls\n", argv[_PyOS_optind - 1]);
+ }
+ return '_';
+ }
+ opt_ptr = L"";
+ if (!opt->has_arg) {
+ return opt->val;
+ }
+ if (_PyOS_optind >= argc) {
+ if (_PyOS_opterr) {
+ fprintf(stderr, "Argument expected for the %ls options\n",
+ argv[_PyOS_optind - 1]);
+ }
+ return '_';
+ }
+ _PyOS_optarg = argv[_PyOS_optind++];
+ return opt->val;
+ }
+
+ if (option == 'J') {
+ if (_PyOS_opterr) {
+ fprintf(stderr, "-J is reserved for Jython\n");
+ }
+ return '_';
+ }
+
+ if ((ptr = wcschr(SHORT_OPTS, option)) == NULL) {
+ if (_PyOS_opterr) {
+ fprintf(stderr, "Unknown option: -%c\n", (char)option);
+ }
+ return '_';
+ }
+
+ if (*(ptr + 1) == L':') {
+ if (*opt_ptr != L'\0') {
+ _PyOS_optarg = opt_ptr;
+ opt_ptr = L"";
+ }
+
+ else {
+ if (_PyOS_optind >= argc) {
+ if (_PyOS_opterr) {
+ fprintf(stderr,
+ "Argument expected for the -%c option\n", (char)option);
+ }
+ return '_';
+ }
+
+ _PyOS_optarg = argv[_PyOS_optind++];
+ }
+ }
+
+ return option;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/contrib/tools/python3/src/Python/getplatform.c b/contrib/tools/python3/src/Python/getplatform.c
new file mode 100644
index 00000000000..81a0f7ac537
--- /dev/null
+++ b/contrib/tools/python3/src/Python/getplatform.c
@@ -0,0 +1,12 @@
+
+#include "Python.h"
+
+#ifndef PLATFORM
+#define PLATFORM "unknown"
+#endif
+
+const char *
+Py_GetPlatform(void)
+{
+ return PLATFORM;
+}
diff --git a/contrib/tools/python3/src/Python/getversion.c b/contrib/tools/python3/src/Python/getversion.c
new file mode 100644
index 00000000000..c32b6f9d60d
--- /dev/null
+++ b/contrib/tools/python3/src/Python/getversion.c
@@ -0,0 +1,15 @@
+
+/* Return the full version string. */
+
+#include "Python.h"
+
+#include "patchlevel.h"
+
+const char *
+Py_GetVersion(void)
+{
+ static char version[250];
+ PyOS_snprintf(version, sizeof(version), "%.80s (%.80s) %.80s",
+ PY_VERSION, Py_GetBuildInfo(), Py_GetCompiler());
+ return version;
+}
diff --git a/contrib/tools/python3/src/Python/graminit.c b/contrib/tools/python3/src/Python/graminit.c
new file mode 100644
index 00000000000..b7aa52895f8
--- /dev/null
+++ b/contrib/tools/python3/src/Python/graminit.c
@@ -0,0 +1,2688 @@
+/* Generated by Parser/pgen */
+
+#include "exports.h"
+#include "grammar.h"
+Py_EXPORTED_SYMBOL grammar _PyParser_Grammar;
+static const arc arcs_0_0[3] = {
+ {2, 1},
+ {3, 2},
+ {4, 1},
+};
+static const arc arcs_0_1[1] = {
+ {0, 1},
+};
+static const arc arcs_0_2[1] = {
+ {2, 1},
+};
+static state states_0[3] = {
+ {3, arcs_0_0},
+ {1, arcs_0_1},
+ {1, arcs_0_2},
+};
+static const arc arcs_1_0[3] = {
+ {44, 1},
+ {2, 0},
+ {45, 0},
+};
+static const arc arcs_1_1[1] = {
+ {0, 1},
+};
+static state states_1[2] = {
+ {3, arcs_1_0},
+ {1, arcs_1_1},
+};
+static const arc arcs_2_0[1] = {
+ {47, 1},
+};
+static const arc arcs_2_1[2] = {
+ {44, 2},
+ {2, 1},
+};
+static const arc arcs_2_2[1] = {
+ {0, 2},
+};
+static state states_2[3] = {
+ {1, arcs_2_0},
+ {2, arcs_2_1},
+ {1, arcs_2_2},
+};
+static const arc arcs_3_0[1] = {
+ {10, 1},
+};
+static const arc arcs_3_1[1] = {
+ {49, 2},
+};
+static const arc arcs_3_2[1] = {
+ {2, 3},
+};
+static const arc arcs_3_3[1] = {
+ {0, 3},
+};
+static state states_3[4] = {
+ {1, arcs_3_0},
+ {1, arcs_3_1},
+ {1, arcs_3_2},
+ {1, arcs_3_3},
+};
+static const arc arcs_4_0[1] = {
+ {48, 1},
+};
+static const arc arcs_4_1[2] = {
+ {48, 1},
+ {0, 1},
+};
+static state states_4[2] = {
+ {1, arcs_4_0},
+ {2, arcs_4_1},
+};
+static const arc arcs_5_0[1] = {
+ {50, 1},
+};
+static const arc arcs_5_1[3] = {
+ {52, 2},
+ {53, 2},
+ {54, 2},
+};
+static const arc arcs_5_2[1] = {
+ {0, 2},
+};
+static state states_5[3] = {
+ {1, arcs_5_0},
+ {3, arcs_5_1},
+ {1, arcs_5_2},
+};
+static const arc arcs_6_0[1] = {
+ {38, 1},
+};
+static const arc arcs_6_1[1] = {
+ {54, 2},
+};
+static const arc arcs_6_2[1] = {
+ {0, 2},
+};
+static state states_6[3] = {
+ {1, arcs_6_0},
+ {1, arcs_6_1},
+ {1, arcs_6_2},
+};
+static const arc arcs_7_0[1] = {
+ {19, 1},
+};
+static const arc arcs_7_1[1] = {
+ {40, 2},
+};
+static const arc arcs_7_2[1] = {
+ {55, 3},
+};
+static const arc arcs_7_3[2] = {
+ {56, 4},
+ {57, 5},
+};
+static const arc arcs_7_4[1] = {
+ {58, 6},
+};
+static const arc arcs_7_5[2] = {
+ {59, 7},
+ {60, 8},
+};
+static const arc arcs_7_6[1] = {
+ {57, 5},
+};
+static const arc arcs_7_7[1] = {
+ {60, 8},
+};
+static const arc arcs_7_8[1] = {
+ {0, 8},
+};
+static state states_7[9] = {
+ {1, arcs_7_0},
+ {1, arcs_7_1},
+ {1, arcs_7_2},
+ {2, arcs_7_3},
+ {1, arcs_7_4},
+ {2, arcs_7_5},
+ {1, arcs_7_6},
+ {1, arcs_7_7},
+ {1, arcs_7_8},
+};
+static const arc arcs_8_0[1] = {
+ {5, 1},
+};
+static const arc arcs_8_1[2] = {
+ {61, 2},
+ {62, 3},
+};
+static const arc arcs_8_2[1] = {
+ {0, 2},
+};
+static const arc arcs_8_3[1] = {
+ {61, 2},
+};
+static state states_8[4] = {
+ {1, arcs_8_0},
+ {2, arcs_8_1},
+ {1, arcs_8_2},
+ {1, arcs_8_3},
+};
+static const arc arcs_9_0[3] = {
+ {6, 1},
+ {63, 2},
+ {64, 3},
+};
+static const arc arcs_9_1[4] = {
+ {65, 4},
+ {59, 5},
+ {64, 6},
+ {0, 1},
+};
+static const arc arcs_9_2[1] = {
+ {64, 7},
+};
+static const arc arcs_9_3[4] = {
+ {65, 8},
+ {66, 9},
+ {59, 5},
+ {0, 3},
+};
+static const arc arcs_9_4[4] = {
+ {63, 2},
+ {59, 10},
+ {64, 11},
+ {0, 4},
+};
+static const arc arcs_9_5[1] = {
+ {0, 5},
+};
+static const arc arcs_9_6[3] = {
+ {65, 4},
+ {59, 5},
+ {0, 6},
+};
+static const arc arcs_9_7[3] = {
+ {65, 12},
+ {59, 5},
+ {0, 7},
+};
+static const arc arcs_9_8[6] = {
+ {6, 13},
+ {63, 2},
+ {67, 14},
+ {59, 15},
+ {64, 3},
+ {0, 8},
+};
+static const arc arcs_9_9[1] = {
+ {58, 16},
+};
+static const arc arcs_9_10[3] = {
+ {63, 2},
+ {64, 11},
+ {0, 10},
+};
+static const arc arcs_9_11[4] = {
+ {65, 4},
+ {66, 17},
+ {59, 5},
+ {0, 11},
+};
+static const arc arcs_9_12[2] = {
+ {59, 5},
+ {0, 12},
+};
+static const arc arcs_9_13[4] = {
+ {65, 18},
+ {59, 5},
+ {64, 19},
+ {0, 13},
+};
+static const arc arcs_9_14[2] = {
+ {65, 20},
+ {0, 14},
+};
+static const arc arcs_9_15[5] = {
+ {6, 13},
+ {63, 2},
+ {67, 14},
+ {64, 3},
+ {0, 15},
+};
+static const arc arcs_9_16[3] = {
+ {65, 8},
+ {59, 5},
+ {0, 16},
+};
+static const arc arcs_9_17[1] = {
+ {58, 6},
+};
+static const arc arcs_9_18[4] = {
+ {63, 2},
+ {59, 21},
+ {64, 22},
+ {0, 18},
+};
+static const arc arcs_9_19[3] = {
+ {65, 18},
+ {59, 5},
+ {0, 19},
+};
+static const arc arcs_9_20[5] = {
+ {6, 23},
+ {63, 2},
+ {59, 24},
+ {64, 25},
+ {0, 20},
+};
+static const arc arcs_9_21[3] = {
+ {63, 2},
+ {64, 22},
+ {0, 21},
+};
+static const arc arcs_9_22[4] = {
+ {65, 18},
+ {66, 26},
+ {59, 5},
+ {0, 22},
+};
+static const arc arcs_9_23[4] = {
+ {65, 27},
+ {59, 5},
+ {64, 28},
+ {0, 23},
+};
+static const arc arcs_9_24[1] = {
+ {64, 25},
+};
+static const arc arcs_9_25[4] = {
+ {65, 29},
+ {66, 30},
+ {59, 5},
+ {0, 25},
+};
+static const arc arcs_9_26[1] = {
+ {58, 19},
+};
+static const arc arcs_9_27[4] = {
+ {63, 2},
+ {59, 31},
+ {64, 32},
+ {0, 27},
+};
+static const arc arcs_9_28[3] = {
+ {65, 27},
+ {59, 5},
+ {0, 28},
+};
+static const arc arcs_9_29[5] = {
+ {6, 33},
+ {63, 2},
+ {59, 34},
+ {64, 25},
+ {0, 29},
+};
+static const arc arcs_9_30[1] = {
+ {58, 35},
+};
+static const arc arcs_9_31[3] = {
+ {63, 2},
+ {64, 32},
+ {0, 31},
+};
+static const arc arcs_9_32[4] = {
+ {65, 27},
+ {66, 36},
+ {59, 5},
+ {0, 32},
+};
+static const arc arcs_9_33[4] = {
+ {65, 37},
+ {59, 5},
+ {64, 38},
+ {0, 33},
+};
+static const arc arcs_9_34[4] = {
+ {6, 33},
+ {63, 2},
+ {64, 25},
+ {0, 34},
+};
+static const arc arcs_9_35[3] = {
+ {65, 29},
+ {59, 5},
+ {0, 35},
+};
+static const arc arcs_9_36[1] = {
+ {58, 28},
+};
+static const arc arcs_9_37[4] = {
+ {63, 2},
+ {59, 39},
+ {64, 40},
+ {0, 37},
+};
+static const arc arcs_9_38[3] = {
+ {65, 37},
+ {59, 5},
+ {0, 38},
+};
+static const arc arcs_9_39[3] = {
+ {63, 2},
+ {64, 40},
+ {0, 39},
+};
+static const arc arcs_9_40[4] = {
+ {65, 37},
+ {66, 41},
+ {59, 5},
+ {0, 40},
+};
+static const arc arcs_9_41[1] = {
+ {58, 38},
+};
+static state states_9[42] = {
+ {3, arcs_9_0},
+ {4, arcs_9_1},
+ {1, arcs_9_2},
+ {4, arcs_9_3},
+ {4, arcs_9_4},
+ {1, arcs_9_5},
+ {3, arcs_9_6},
+ {3, arcs_9_7},
+ {6, arcs_9_8},
+ {1, arcs_9_9},
+ {3, arcs_9_10},
+ {4, arcs_9_11},
+ {2, arcs_9_12},
+ {4, arcs_9_13},
+ {2, arcs_9_14},
+ {5, arcs_9_15},
+ {3, arcs_9_16},
+ {1, arcs_9_17},
+ {4, arcs_9_18},
+ {3, arcs_9_19},
+ {5, arcs_9_20},
+ {3, arcs_9_21},
+ {4, arcs_9_22},
+ {4, arcs_9_23},
+ {1, arcs_9_24},
+ {4, arcs_9_25},
+ {1, arcs_9_26},
+ {4, arcs_9_27},
+ {3, arcs_9_28},
+ {5, arcs_9_29},
+ {1, arcs_9_30},
+ {3, arcs_9_31},
+ {4, arcs_9_32},
+ {4, arcs_9_33},
+ {4, arcs_9_34},
+ {3, arcs_9_35},
+ {1, arcs_9_36},
+ {4, arcs_9_37},
+ {3, arcs_9_38},
+ {3, arcs_9_39},
+ {4, arcs_9_40},
+ {1, arcs_9_41},
+};
+static const arc arcs_10_0[1] = {
+ {40, 1},
+};
+static const arc arcs_10_1[2] = {
+ {57, 2},
+ {0, 1},
+};
+static const arc arcs_10_2[1] = {
+ {58, 3},
+};
+static const arc arcs_10_3[1] = {
+ {0, 3},
+};
+static state states_10[4] = {
+ {1, arcs_10_0},
+ {2, arcs_10_1},
+ {1, arcs_10_2},
+ {1, arcs_10_3},
+};
+static const arc arcs_11_0[3] = {
+ {6, 1},
+ {63, 2},
+ {69, 3},
+};
+static const arc arcs_11_1[3] = {
+ {65, 4},
+ {69, 5},
+ {0, 1},
+};
+static const arc arcs_11_2[1] = {
+ {69, 6},
+};
+static const arc arcs_11_3[3] = {
+ {65, 7},
+ {66, 8},
+ {0, 3},
+};
+static const arc arcs_11_4[3] = {
+ {63, 2},
+ {69, 9},
+ {0, 4},
+};
+static const arc arcs_11_5[2] = {
+ {65, 4},
+ {0, 5},
+};
+static const arc arcs_11_6[2] = {
+ {65, 10},
+ {0, 6},
+};
+static const arc arcs_11_7[5] = {
+ {6, 11},
+ {63, 2},
+ {67, 12},
+ {69, 3},
+ {0, 7},
+};
+static const arc arcs_11_8[1] = {
+ {58, 13},
+};
+static const arc arcs_11_9[3] = {
+ {65, 4},
+ {66, 14},
+ {0, 9},
+};
+static const arc arcs_11_10[1] = {
+ {0, 10},
+};
+static const arc arcs_11_11[3] = {
+ {65, 15},
+ {69, 16},
+ {0, 11},
+};
+static const arc arcs_11_12[2] = {
+ {65, 17},
+ {0, 12},
+};
+static const arc arcs_11_13[2] = {
+ {65, 7},
+ {0, 13},
+};
+static const arc arcs_11_14[1] = {
+ {58, 5},
+};
+static const arc arcs_11_15[3] = {
+ {63, 2},
+ {69, 18},
+ {0, 15},
+};
+static const arc arcs_11_16[2] = {
+ {65, 15},
+ {0, 16},
+};
+static const arc arcs_11_17[4] = {
+ {6, 19},
+ {63, 2},
+ {69, 20},
+ {0, 17},
+};
+static const arc arcs_11_18[3] = {
+ {65, 15},
+ {66, 21},
+ {0, 18},
+};
+static const arc arcs_11_19[3] = {
+ {65, 22},
+ {69, 23},
+ {0, 19},
+};
+static const arc arcs_11_20[3] = {
+ {65, 24},
+ {66, 25},
+ {0, 20},
+};
+static const arc arcs_11_21[1] = {
+ {58, 16},
+};
+static const arc arcs_11_22[3] = {
+ {63, 2},
+ {69, 26},
+ {0, 22},
+};
+static const arc arcs_11_23[2] = {
+ {65, 22},
+ {0, 23},
+};
+static const arc arcs_11_24[4] = {
+ {6, 27},
+ {63, 2},
+ {69, 20},
+ {0, 24},
+};
+static const arc arcs_11_25[1] = {
+ {58, 28},
+};
+static const arc arcs_11_26[3] = {
+ {65, 22},
+ {66, 29},
+ {0, 26},
+};
+static const arc arcs_11_27[3] = {
+ {65, 30},
+ {69, 31},
+ {0, 27},
+};
+static const arc arcs_11_28[2] = {
+ {65, 24},
+ {0, 28},
+};
+static const arc arcs_11_29[1] = {
+ {58, 23},
+};
+static const arc arcs_11_30[3] = {
+ {63, 2},
+ {69, 32},
+ {0, 30},
+};
+static const arc arcs_11_31[2] = {
+ {65, 30},
+ {0, 31},
+};
+static const arc arcs_11_32[3] = {
+ {65, 30},
+ {66, 33},
+ {0, 32},
+};
+static const arc arcs_11_33[1] = {
+ {58, 31},
+};
+static state states_11[34] = {
+ {3, arcs_11_0},
+ {3, arcs_11_1},
+ {1, arcs_11_2},
+ {3, arcs_11_3},
+ {3, arcs_11_4},
+ {2, arcs_11_5},
+ {2, arcs_11_6},
+ {5, arcs_11_7},
+ {1, arcs_11_8},
+ {3, arcs_11_9},
+ {1, arcs_11_10},
+ {3, arcs_11_11},
+ {2, arcs_11_12},
+ {2, arcs_11_13},
+ {1, arcs_11_14},
+ {3, arcs_11_15},
+ {2, arcs_11_16},
+ {4, arcs_11_17},
+ {3, arcs_11_18},
+ {3, arcs_11_19},
+ {3, arcs_11_20},
+ {1, arcs_11_21},
+ {3, arcs_11_22},
+ {2, arcs_11_23},
+ {4, arcs_11_24},
+ {1, arcs_11_25},
+ {3, arcs_11_26},
+ {3, arcs_11_27},
+ {2, arcs_11_28},
+ {1, arcs_11_29},
+ {3, arcs_11_30},
+ {2, arcs_11_31},
+ {3, arcs_11_32},
+ {1, arcs_11_33},
+};
+static const arc arcs_12_0[1] = {
+ {40, 1},
+};
+static const arc arcs_12_1[1] = {
+ {0, 1},
+};
+static state states_12[2] = {
+ {1, arcs_12_0},
+ {1, arcs_12_1},
+};
+static const arc arcs_13_0[2] = {
+ {3, 1},
+ {4, 1},
+};
+static const arc arcs_13_1[1] = {
+ {0, 1},
+};
+static state states_13[2] = {
+ {2, arcs_13_0},
+ {1, arcs_13_1},
+};
+static const arc arcs_14_0[1] = {
+ {70, 1},
+};
+static const arc arcs_14_1[2] = {
+ {71, 2},
+ {2, 3},
+};
+static const arc arcs_14_2[2] = {
+ {2, 3},
+ {70, 1},
+};
+static const arc arcs_14_3[1] = {
+ {0, 3},
+};
+static state states_14[4] = {
+ {1, arcs_14_0},
+ {2, arcs_14_1},
+ {2, arcs_14_2},
+ {1, arcs_14_3},
+};
+static const arc arcs_15_0[8] = {
+ {72, 1},
+ {73, 1},
+ {74, 1},
+ {75, 1},
+ {76, 1},
+ {77, 1},
+ {78, 1},
+ {79, 1},
+};
+static const arc arcs_15_1[1] = {
+ {0, 1},
+};
+static state states_15[2] = {
+ {8, arcs_15_0},
+ {1, arcs_15_1},
+};
+static const arc arcs_16_0[1] = {
+ {80, 1},
+};
+static const arc arcs_16_1[4] = {
+ {66, 2},
+ {81, 3},
+ {82, 4},
+ {0, 1},
+};
+static const arc arcs_16_2[2] = {
+ {80, 5},
+ {83, 5},
+};
+static const arc arcs_16_3[1] = {
+ {0, 3},
+};
+static const arc arcs_16_4[2] = {
+ {47, 3},
+ {83, 3},
+};
+static const arc arcs_16_5[3] = {
+ {66, 2},
+ {59, 3},
+ {0, 5},
+};
+static state states_16[6] = {
+ {1, arcs_16_0},
+ {4, arcs_16_1},
+ {2, arcs_16_2},
+ {1, arcs_16_3},
+ {2, arcs_16_4},
+ {3, arcs_16_5},
+};
+static const arc arcs_17_0[1] = {
+ {57, 1},
+};
+static const arc arcs_17_1[1] = {
+ {58, 2},
+};
+static const arc arcs_17_2[2] = {
+ {66, 3},
+ {0, 2},
+};
+static const arc arcs_17_3[2] = {
+ {80, 4},
+ {83, 4},
+};
+static const arc arcs_17_4[1] = {
+ {0, 4},
+};
+static state states_17[5] = {
+ {1, arcs_17_0},
+ {1, arcs_17_1},
+ {2, arcs_17_2},
+ {2, arcs_17_3},
+ {1, arcs_17_4},
+};
+static const arc arcs_18_0[2] = {
+ {84, 1},
+ {58, 1},
+};
+static const arc arcs_18_1[2] = {
+ {65, 2},
+ {0, 1},
+};
+static const arc arcs_18_2[3] = {
+ {84, 1},
+ {58, 1},
+ {0, 2},
+};
+static state states_18[3] = {
+ {2, arcs_18_0},
+ {2, arcs_18_1},
+ {3, arcs_18_2},
+};
+static const arc arcs_19_0[13] = {
+ {85, 1},
+ {86, 1},
+ {87, 1},
+ {88, 1},
+ {89, 1},
+ {90, 1},
+ {91, 1},
+ {92, 1},
+ {93, 1},
+ {94, 1},
+ {95, 1},
+ {96, 1},
+ {97, 1},
+};
+static const arc arcs_19_1[1] = {
+ {0, 1},
+};
+static state states_19[2] = {
+ {13, arcs_19_0},
+ {1, arcs_19_1},
+};
+static const arc arcs_20_0[1] = {
+ {20, 1},
+};
+static const arc arcs_20_1[1] = {
+ {98, 2},
+};
+static const arc arcs_20_2[1] = {
+ {0, 2},
+};
+static state states_20[3] = {
+ {1, arcs_20_0},
+ {1, arcs_20_1},
+ {1, arcs_20_2},
+};
+static const arc arcs_21_0[1] = {
+ {29, 1},
+};
+static const arc arcs_21_1[1] = {
+ {0, 1},
+};
+static state states_21[2] = {
+ {1, arcs_21_0},
+ {1, arcs_21_1},
+};
+static const arc arcs_22_0[5] = {
+ {99, 1},
+ {100, 1},
+ {101, 1},
+ {102, 1},
+ {103, 1},
+};
+static const arc arcs_22_1[1] = {
+ {0, 1},
+};
+static state states_22[2] = {
+ {5, arcs_22_0},
+ {1, arcs_22_1},
+};
+static const arc arcs_23_0[1] = {
+ {16, 1},
+};
+static const arc arcs_23_1[1] = {
+ {0, 1},
+};
+static state states_23[2] = {
+ {1, arcs_23_0},
+ {1, arcs_23_1},
+};
+static const arc arcs_24_0[1] = {
+ {18, 1},
+};
+static const arc arcs_24_1[1] = {
+ {0, 1},
+};
+static state states_24[2] = {
+ {1, arcs_24_0},
+ {1, arcs_24_1},
+};
+static const arc arcs_25_0[1] = {
+ {31, 1},
+};
+static const arc arcs_25_1[2] = {
+ {80, 2},
+ {0, 1},
+};
+static const arc arcs_25_2[1] = {
+ {0, 2},
+};
+static state states_25[3] = {
+ {1, arcs_25_0},
+ {2, arcs_25_1},
+ {1, arcs_25_2},
+};
+static const arc arcs_26_0[1] = {
+ {83, 1},
+};
+static const arc arcs_26_1[1] = {
+ {0, 1},
+};
+static state states_26[2] = {
+ {1, arcs_26_0},
+ {1, arcs_26_1},
+};
+static const arc arcs_27_0[1] = {
+ {30, 1},
+};
+static const arc arcs_27_1[2] = {
+ {58, 2},
+ {0, 1},
+};
+static const arc arcs_27_2[2] = {
+ {22, 3},
+ {0, 2},
+};
+static const arc arcs_27_3[1] = {
+ {58, 4},
+};
+static const arc arcs_27_4[1] = {
+ {0, 4},
+};
+static state states_27[5] = {
+ {1, arcs_27_0},
+ {2, arcs_27_1},
+ {2, arcs_27_2},
+ {1, arcs_27_3},
+ {1, arcs_27_4},
+};
+static const arc arcs_28_0[2] = {
+ {104, 1},
+ {105, 1},
+};
+static const arc arcs_28_1[1] = {
+ {0, 1},
+};
+static state states_28[2] = {
+ {2, arcs_28_0},
+ {1, arcs_28_1},
+};
+static const arc arcs_29_0[1] = {
+ {25, 1},
+};
+static const arc arcs_29_1[1] = {
+ {106, 2},
+};
+static const arc arcs_29_2[1] = {
+ {0, 2},
+};
+static state states_29[3] = {
+ {1, arcs_29_0},
+ {1, arcs_29_1},
+ {1, arcs_29_2},
+};
+static const arc arcs_30_0[1] = {
+ {22, 1},
+};
+static const arc arcs_30_1[3] = {
+ {107, 2},
+ {9, 2},
+ {108, 3},
+};
+static const arc arcs_30_2[4] = {
+ {107, 2},
+ {9, 2},
+ {25, 4},
+ {108, 3},
+};
+static const arc arcs_30_3[1] = {
+ {25, 4},
+};
+static const arc arcs_30_4[3] = {
+ {5, 5},
+ {6, 6},
+ {109, 6},
+};
+static const arc arcs_30_5[1] = {
+ {109, 7},
+};
+static const arc arcs_30_6[1] = {
+ {0, 6},
+};
+static const arc arcs_30_7[1] = {
+ {61, 6},
+};
+static state states_30[8] = {
+ {1, arcs_30_0},
+ {3, arcs_30_1},
+ {4, arcs_30_2},
+ {1, arcs_30_3},
+ {3, arcs_30_4},
+ {1, arcs_30_5},
+ {1, arcs_30_6},
+ {1, arcs_30_7},
+};
+static const arc arcs_31_0[1] = {
+ {40, 1},
+};
+static const arc arcs_31_1[2] = {
+ {111, 2},
+ {0, 1},
+};
+static const arc arcs_31_2[1] = {
+ {40, 3},
+};
+static const arc arcs_31_3[1] = {
+ {0, 3},
+};
+static state states_31[4] = {
+ {1, arcs_31_0},
+ {2, arcs_31_1},
+ {1, arcs_31_2},
+ {1, arcs_31_3},
+};
+static const arc arcs_32_0[1] = {
+ {108, 1},
+};
+static const arc arcs_32_1[2] = {
+ {111, 2},
+ {0, 1},
+};
+static const arc arcs_32_2[1] = {
+ {40, 3},
+};
+static const arc arcs_32_3[1] = {
+ {0, 3},
+};
+static state states_32[4] = {
+ {1, arcs_32_0},
+ {2, arcs_32_1},
+ {1, arcs_32_2},
+ {1, arcs_32_3},
+};
+static const arc arcs_33_0[1] = {
+ {110, 1},
+};
+static const arc arcs_33_1[2] = {
+ {65, 2},
+ {0, 1},
+};
+static const arc arcs_33_2[2] = {
+ {110, 1},
+ {0, 2},
+};
+static state states_33[3] = {
+ {1, arcs_33_0},
+ {2, arcs_33_1},
+ {2, arcs_33_2},
+};
+static const arc arcs_34_0[1] = {
+ {112, 1},
+};
+static const arc arcs_34_1[2] = {
+ {65, 0},
+ {0, 1},
+};
+static state states_34[2] = {
+ {1, arcs_34_0},
+ {2, arcs_34_1},
+};
+static const arc arcs_35_0[1] = {
+ {40, 1},
+};
+static const arc arcs_35_1[2] = {
+ {107, 0},
+ {0, 1},
+};
+static state states_35[2] = {
+ {1, arcs_35_0},
+ {2, arcs_35_1},
+};
+static const arc arcs_36_0[1] = {
+ {23, 1},
+};
+static const arc arcs_36_1[1] = {
+ {40, 2},
+};
+static const arc arcs_36_2[2] = {
+ {65, 1},
+ {0, 2},
+};
+static state states_36[3] = {
+ {1, arcs_36_0},
+ {1, arcs_36_1},
+ {2, arcs_36_2},
+};
+static const arc arcs_37_0[1] = {
+ {27, 1},
+};
+static const arc arcs_37_1[1] = {
+ {40, 2},
+};
+static const arc arcs_37_2[2] = {
+ {65, 1},
+ {0, 2},
+};
+static state states_37[3] = {
+ {1, arcs_37_0},
+ {1, arcs_37_1},
+ {2, arcs_37_2},
+};
+static const arc arcs_38_0[1] = {
+ {15, 1},
+};
+static const arc arcs_38_1[1] = {
+ {58, 2},
+};
+static const arc arcs_38_2[2] = {
+ {65, 3},
+ {0, 2},
+};
+static const arc arcs_38_3[1] = {
+ {58, 4},
+};
+static const arc arcs_38_4[1] = {
+ {0, 4},
+};
+static state states_38[5] = {
+ {1, arcs_38_0},
+ {1, arcs_38_1},
+ {2, arcs_38_2},
+ {1, arcs_38_3},
+ {1, arcs_38_4},
+};
+static const arc arcs_39_0[9] = {
+ {113, 1},
+ {53, 1},
+ {51, 1},
+ {114, 1},
+ {54, 1},
+ {115, 1},
+ {116, 1},
+ {117, 1},
+ {118, 1},
+};
+static const arc arcs_39_1[1] = {
+ {0, 1},
+};
+static state states_39[2] = {
+ {9, arcs_39_0},
+ {1, arcs_39_1},
+};
+static const arc arcs_40_0[1] = {
+ {38, 1},
+};
+static const arc arcs_40_1[3] = {
+ {114, 2},
+ {54, 2},
+ {118, 2},
+};
+static const arc arcs_40_2[1] = {
+ {0, 2},
+};
+static state states_40[3] = {
+ {1, arcs_40_0},
+ {3, arcs_40_1},
+ {1, arcs_40_2},
+};
+static const arc arcs_41_0[1] = {
+ {24, 1},
+};
+static const arc arcs_41_1[1] = {
+ {49, 2},
+};
+static const arc arcs_41_2[1] = {
+ {57, 3},
+};
+static const arc arcs_41_3[1] = {
+ {119, 4},
+};
+static const arc arcs_41_4[3] = {
+ {120, 1},
+ {121, 5},
+ {0, 4},
+};
+static const arc arcs_41_5[1] = {
+ {57, 6},
+};
+static const arc arcs_41_6[1] = {
+ {119, 7},
+};
+static const arc arcs_41_7[1] = {
+ {0, 7},
+};
+static state states_41[8] = {
+ {1, arcs_41_0},
+ {1, arcs_41_1},
+ {1, arcs_41_2},
+ {1, arcs_41_3},
+ {3, arcs_41_4},
+ {1, arcs_41_5},
+ {1, arcs_41_6},
+ {1, arcs_41_7},
+};
+static const arc arcs_42_0[1] = {
+ {33, 1},
+};
+static const arc arcs_42_1[1] = {
+ {49, 2},
+};
+static const arc arcs_42_2[1] = {
+ {57, 3},
+};
+static const arc arcs_42_3[1] = {
+ {119, 4},
+};
+static const arc arcs_42_4[2] = {
+ {121, 5},
+ {0, 4},
+};
+static const arc arcs_42_5[1] = {
+ {57, 6},
+};
+static const arc arcs_42_6[1] = {
+ {119, 7},
+};
+static const arc arcs_42_7[1] = {
+ {0, 7},
+};
+static state states_42[8] = {
+ {1, arcs_42_0},
+ {1, arcs_42_1},
+ {1, arcs_42_2},
+ {1, arcs_42_3},
+ {2, arcs_42_4},
+ {1, arcs_42_5},
+ {1, arcs_42_6},
+ {1, arcs_42_7},
+};
+static const arc arcs_43_0[1] = {
+ {21, 1},
+};
+static const arc arcs_43_1[1] = {
+ {98, 2},
+};
+static const arc arcs_43_2[1] = {
+ {122, 3},
+};
+static const arc arcs_43_3[1] = {
+ {47, 4},
+};
+static const arc arcs_43_4[1] = {
+ {57, 5},
+};
+static const arc arcs_43_5[2] = {
+ {59, 6},
+ {119, 7},
+};
+static const arc arcs_43_6[1] = {
+ {119, 7},
+};
+static const arc arcs_43_7[2] = {
+ {121, 8},
+ {0, 7},
+};
+static const arc arcs_43_8[1] = {
+ {57, 9},
+};
+static const arc arcs_43_9[1] = {
+ {119, 10},
+};
+static const arc arcs_43_10[1] = {
+ {0, 10},
+};
+static state states_43[11] = {
+ {1, arcs_43_0},
+ {1, arcs_43_1},
+ {1, arcs_43_2},
+ {1, arcs_43_3},
+ {1, arcs_43_4},
+ {2, arcs_43_5},
+ {1, arcs_43_6},
+ {2, arcs_43_7},
+ {1, arcs_43_8},
+ {1, arcs_43_9},
+ {1, arcs_43_10},
+};
+static const arc arcs_44_0[1] = {
+ {32, 1},
+};
+static const arc arcs_44_1[1] = {
+ {57, 2},
+};
+static const arc arcs_44_2[1] = {
+ {119, 3},
+};
+static const arc arcs_44_3[2] = {
+ {123, 4},
+ {124, 5},
+};
+static const arc arcs_44_4[1] = {
+ {57, 6},
+};
+static const arc arcs_44_5[1] = {
+ {57, 7},
+};
+static const arc arcs_44_6[1] = {
+ {119, 8},
+};
+static const arc arcs_44_7[1] = {
+ {119, 9},
+};
+static const arc arcs_44_8[1] = {
+ {0, 8},
+};
+static const arc arcs_44_9[4] = {
+ {121, 10},
+ {123, 4},
+ {124, 5},
+ {0, 9},
+};
+static const arc arcs_44_10[1] = {
+ {57, 11},
+};
+static const arc arcs_44_11[1] = {
+ {119, 12},
+};
+static const arc arcs_44_12[2] = {
+ {123, 4},
+ {0, 12},
+};
+static state states_44[13] = {
+ {1, arcs_44_0},
+ {1, arcs_44_1},
+ {1, arcs_44_2},
+ {2, arcs_44_3},
+ {1, arcs_44_4},
+ {1, arcs_44_5},
+ {1, arcs_44_6},
+ {1, arcs_44_7},
+ {1, arcs_44_8},
+ {4, arcs_44_9},
+ {1, arcs_44_10},
+ {1, arcs_44_11},
+ {2, arcs_44_12},
+};
+static const arc arcs_45_0[1] = {
+ {34, 1},
+};
+static const arc arcs_45_1[1] = {
+ {125, 2},
+};
+static const arc arcs_45_2[2] = {
+ {65, 1},
+ {57, 3},
+};
+static const arc arcs_45_3[2] = {
+ {59, 4},
+ {119, 5},
+};
+static const arc arcs_45_4[1] = {
+ {119, 5},
+};
+static const arc arcs_45_5[1] = {
+ {0, 5},
+};
+static state states_45[6] = {
+ {1, arcs_45_0},
+ {1, arcs_45_1},
+ {2, arcs_45_2},
+ {2, arcs_45_3},
+ {1, arcs_45_4},
+ {1, arcs_45_5},
+};
+static const arc arcs_46_0[1] = {
+ {58, 1},
+};
+static const arc arcs_46_1[2] = {
+ {111, 2},
+ {0, 1},
+};
+static const arc arcs_46_2[1] = {
+ {126, 3},
+};
+static const arc arcs_46_3[1] = {
+ {0, 3},
+};
+static state states_46[4] = {
+ {1, arcs_46_0},
+ {2, arcs_46_1},
+ {1, arcs_46_2},
+ {1, arcs_46_3},
+};
+static const arc arcs_47_0[1] = {
+ {127, 1},
+};
+static const arc arcs_47_1[2] = {
+ {58, 2},
+ {0, 1},
+};
+static const arc arcs_47_2[2] = {
+ {111, 3},
+ {0, 2},
+};
+static const arc arcs_47_3[1] = {
+ {40, 4},
+};
+static const arc arcs_47_4[1] = {
+ {0, 4},
+};
+static state states_47[5] = {
+ {1, arcs_47_0},
+ {2, arcs_47_1},
+ {2, arcs_47_2},
+ {1, arcs_47_3},
+ {1, arcs_47_4},
+};
+static const arc arcs_48_0[2] = {
+ {2, 1},
+ {4, 2},
+};
+static const arc arcs_48_1[1] = {
+ {128, 3},
+};
+static const arc arcs_48_2[1] = {
+ {0, 2},
+};
+static const arc arcs_48_3[1] = {
+ {45, 4},
+};
+static const arc arcs_48_4[2] = {
+ {129, 2},
+ {45, 4},
+};
+static state states_48[5] = {
+ {2, arcs_48_0},
+ {1, arcs_48_1},
+ {1, arcs_48_2},
+ {1, arcs_48_3},
+ {2, arcs_48_4},
+};
+static const arc arcs_49_0[1] = {
+ {58, 1},
+};
+static const arc arcs_49_1[2] = {
+ {130, 2},
+ {0, 1},
+};
+static const arc arcs_49_2[1] = {
+ {58, 3},
+};
+static const arc arcs_49_3[1] = {
+ {0, 3},
+};
+static state states_49[4] = {
+ {1, arcs_49_0},
+ {2, arcs_49_1},
+ {1, arcs_49_2},
+ {1, arcs_49_3},
+};
+static const arc arcs_50_0[2] = {
+ {131, 1},
+ {132, 2},
+};
+static const arc arcs_50_1[1] = {
+ {0, 1},
+};
+static const arc arcs_50_2[2] = {
+ {24, 3},
+ {0, 2},
+};
+static const arc arcs_50_3[1] = {
+ {132, 4},
+};
+static const arc arcs_50_4[1] = {
+ {121, 5},
+};
+static const arc arcs_50_5[1] = {
+ {58, 1},
+};
+static state states_50[6] = {
+ {2, arcs_50_0},
+ {1, arcs_50_1},
+ {2, arcs_50_2},
+ {1, arcs_50_3},
+ {1, arcs_50_4},
+ {1, arcs_50_5},
+};
+static const arc arcs_51_0[2] = {
+ {134, 1},
+ {132, 1},
+};
+static const arc arcs_51_1[1] = {
+ {0, 1},
+};
+static state states_51[2] = {
+ {2, arcs_51_0},
+ {1, arcs_51_1},
+};
+static const arc arcs_52_0[1] = {
+ {26, 1},
+};
+static const arc arcs_52_1[2] = {
+ {57, 2},
+ {68, 3},
+};
+static const arc arcs_52_2[1] = {
+ {58, 4},
+};
+static const arc arcs_52_3[1] = {
+ {57, 2},
+};
+static const arc arcs_52_4[1] = {
+ {0, 4},
+};
+static state states_52[5] = {
+ {1, arcs_52_0},
+ {2, arcs_52_1},
+ {1, arcs_52_2},
+ {1, arcs_52_3},
+ {1, arcs_52_4},
+};
+static const arc arcs_53_0[1] = {
+ {26, 1},
+};
+static const arc arcs_53_1[2] = {
+ {57, 2},
+ {68, 3},
+};
+static const arc arcs_53_2[1] = {
+ {133, 4},
+};
+static const arc arcs_53_3[1] = {
+ {57, 2},
+};
+static const arc arcs_53_4[1] = {
+ {0, 4},
+};
+static state states_53[5] = {
+ {1, arcs_53_0},
+ {2, arcs_53_1},
+ {1, arcs_53_2},
+ {1, arcs_53_3},
+ {1, arcs_53_4},
+};
+static const arc arcs_54_0[1] = {
+ {135, 1},
+};
+static const arc arcs_54_1[2] = {
+ {136, 0},
+ {0, 1},
+};
+static state states_54[2] = {
+ {1, arcs_54_0},
+ {2, arcs_54_1},
+};
+static const arc arcs_55_0[1] = {
+ {137, 1},
+};
+static const arc arcs_55_1[2] = {
+ {138, 0},
+ {0, 1},
+};
+static state states_55[2] = {
+ {1, arcs_55_0},
+ {2, arcs_55_1},
+};
+static const arc arcs_56_0[2] = {
+ {28, 1},
+ {139, 2},
+};
+static const arc arcs_56_1[1] = {
+ {137, 2},
+};
+static const arc arcs_56_2[1] = {
+ {0, 2},
+};
+static state states_56[3] = {
+ {2, arcs_56_0},
+ {1, arcs_56_1},
+ {1, arcs_56_2},
+};
+static const arc arcs_57_0[1] = {
+ {126, 1},
+};
+static const arc arcs_57_1[2] = {
+ {140, 0},
+ {0, 1},
+};
+static state states_57[2] = {
+ {1, arcs_57_0},
+ {2, arcs_57_1},
+};
+static const arc arcs_58_0[10] = {
+ {141, 1},
+ {142, 1},
+ {143, 1},
+ {141, 1},
+ {144, 1},
+ {145, 1},
+ {146, 1},
+ {122, 1},
+ {147, 2},
+ {28, 3},
+};
+static const arc arcs_58_1[1] = {
+ {0, 1},
+};
+static const arc arcs_58_2[2] = {
+ {28, 1},
+ {0, 2},
+};
+static const arc arcs_58_3[1] = {
+ {122, 1},
+};
+static state states_58[4] = {
+ {10, arcs_58_0},
+ {1, arcs_58_1},
+ {2, arcs_58_2},
+ {1, arcs_58_3},
+};
+static const arc arcs_59_0[1] = {
+ {6, 1},
+};
+static const arc arcs_59_1[1] = {
+ {126, 2},
+};
+static const arc arcs_59_2[1] = {
+ {0, 2},
+};
+static state states_59[3] = {
+ {1, arcs_59_0},
+ {1, arcs_59_1},
+ {1, arcs_59_2},
+};
+static const arc arcs_60_0[1] = {
+ {148, 1},
+};
+static const arc arcs_60_1[2] = {
+ {149, 0},
+ {0, 1},
+};
+static state states_60[2] = {
+ {1, arcs_60_0},
+ {2, arcs_60_1},
+};
+static const arc arcs_61_0[1] = {
+ {150, 1},
+};
+static const arc arcs_61_1[2] = {
+ {151, 0},
+ {0, 1},
+};
+static state states_61[2] = {
+ {1, arcs_61_0},
+ {2, arcs_61_1},
+};
+static const arc arcs_62_0[1] = {
+ {152, 1},
+};
+static const arc arcs_62_1[2] = {
+ {153, 0},
+ {0, 1},
+};
+static state states_62[2] = {
+ {1, arcs_62_0},
+ {2, arcs_62_1},
+};
+static const arc arcs_63_0[1] = {
+ {154, 1},
+};
+static const arc arcs_63_1[3] = {
+ {155, 0},
+ {156, 0},
+ {0, 1},
+};
+static state states_63[2] = {
+ {1, arcs_63_0},
+ {3, arcs_63_1},
+};
+static const arc arcs_64_0[1] = {
+ {157, 1},
+};
+static const arc arcs_64_1[3] = {
+ {7, 0},
+ {8, 0},
+ {0, 1},
+};
+static state states_64[2] = {
+ {1, arcs_64_0},
+ {3, arcs_64_1},
+};
+static const arc arcs_65_0[1] = {
+ {158, 1},
+};
+static const arc arcs_65_1[6] = {
+ {159, 0},
+ {6, 0},
+ {67, 0},
+ {160, 0},
+ {10, 0},
+ {0, 1},
+};
+static state states_65[2] = {
+ {1, arcs_65_0},
+ {6, arcs_65_1},
+};
+static const arc arcs_66_0[4] = {
+ {7, 1},
+ {8, 1},
+ {37, 1},
+ {161, 2},
+};
+static const arc arcs_66_1[1] = {
+ {158, 2},
+};
+static const arc arcs_66_2[1] = {
+ {0, 2},
+};
+static state states_66[3] = {
+ {4, arcs_66_0},
+ {1, arcs_66_1},
+ {1, arcs_66_2},
+};
+static const arc arcs_67_0[1] = {
+ {162, 1},
+};
+static const arc arcs_67_1[2] = {
+ {63, 2},
+ {0, 1},
+};
+static const arc arcs_67_2[1] = {
+ {158, 3},
+};
+static const arc arcs_67_3[1] = {
+ {0, 3},
+};
+static state states_67[4] = {
+ {1, arcs_67_0},
+ {2, arcs_67_1},
+ {1, arcs_67_2},
+ {1, arcs_67_3},
+};
+static const arc arcs_68_0[2] = {
+ {39, 1},
+ {163, 2},
+};
+static const arc arcs_68_1[1] = {
+ {163, 2},
+};
+static const arc arcs_68_2[2] = {
+ {164, 2},
+ {0, 2},
+};
+static state states_68[3] = {
+ {2, arcs_68_0},
+ {1, arcs_68_1},
+ {2, arcs_68_2},
+};
+static const arc arcs_69_0[10] = {
+ {5, 1},
+ {9, 2},
+ {11, 2},
+ {12, 2},
+ {13, 2},
+ {14, 3},
+ {36, 4},
+ {40, 2},
+ {41, 2},
+ {42, 5},
+};
+static const arc arcs_69_1[3] = {
+ {61, 2},
+ {165, 6},
+ {83, 6},
+};
+static const arc arcs_69_2[1] = {
+ {0, 2},
+};
+static const arc arcs_69_3[2] = {
+ {166, 2},
+ {165, 7},
+};
+static const arc arcs_69_4[2] = {
+ {167, 2},
+ {168, 8},
+};
+static const arc arcs_69_5[2] = {
+ {42, 5},
+ {0, 5},
+};
+static const arc arcs_69_6[1] = {
+ {61, 2},
+};
+static const arc arcs_69_7[1] = {
+ {166, 2},
+};
+static const arc arcs_69_8[1] = {
+ {167, 2},
+};
+static state states_69[9] = {
+ {10, arcs_69_0},
+ {3, arcs_69_1},
+ {1, arcs_69_2},
+ {2, arcs_69_3},
+ {2, arcs_69_4},
+ {2, arcs_69_5},
+ {1, arcs_69_6},
+ {1, arcs_69_7},
+ {1, arcs_69_8},
+};
+static const arc arcs_70_0[2] = {
+ {49, 1},
+ {84, 1},
+};
+static const arc arcs_70_1[3] = {
+ {65, 2},
+ {169, 3},
+ {0, 1},
+};
+static const arc arcs_70_2[3] = {
+ {49, 4},
+ {84, 4},
+ {0, 2},
+};
+static const arc arcs_70_3[1] = {
+ {0, 3},
+};
+static const arc arcs_70_4[2] = {
+ {65, 2},
+ {0, 4},
+};
+static state states_70[5] = {
+ {2, arcs_70_0},
+ {3, arcs_70_1},
+ {3, arcs_70_2},
+ {1, arcs_70_3},
+ {2, arcs_70_4},
+};
+static const arc arcs_71_0[3] = {
+ {5, 1},
+ {107, 2},
+ {14, 3},
+};
+static const arc arcs_71_1[2] = {
+ {61, 4},
+ {170, 5},
+};
+static const arc arcs_71_2[1] = {
+ {40, 4},
+};
+static const arc arcs_71_3[1] = {
+ {171, 6},
+};
+static const arc arcs_71_4[1] = {
+ {0, 4},
+};
+static const arc arcs_71_5[1] = {
+ {61, 4},
+};
+static const arc arcs_71_6[1] = {
+ {166, 4},
+};
+static state states_71[7] = {
+ {3, arcs_71_0},
+ {2, arcs_71_1},
+ {1, arcs_71_2},
+ {1, arcs_71_3},
+ {1, arcs_71_4},
+ {1, arcs_71_5},
+ {1, arcs_71_6},
+};
+static const arc arcs_72_0[1] = {
+ {172, 1},
+};
+static const arc arcs_72_1[2] = {
+ {65, 2},
+ {0, 1},
+};
+static const arc arcs_72_2[2] = {
+ {172, 1},
+ {0, 2},
+};
+static state states_72[3] = {
+ {1, arcs_72_0},
+ {2, arcs_72_1},
+ {2, arcs_72_2},
+};
+static const arc arcs_73_0[2] = {
+ {57, 1},
+ {58, 2},
+};
+static const arc arcs_73_1[3] = {
+ {173, 3},
+ {58, 4},
+ {0, 1},
+};
+static const arc arcs_73_2[2] = {
+ {57, 1},
+ {0, 2},
+};
+static const arc arcs_73_3[1] = {
+ {0, 3},
+};
+static const arc arcs_73_4[2] = {
+ {173, 3},
+ {0, 4},
+};
+static state states_73[5] = {
+ {2, arcs_73_0},
+ {3, arcs_73_1},
+ {2, arcs_73_2},
+ {1, arcs_73_3},
+ {2, arcs_73_4},
+};
+static const arc arcs_74_0[1] = {
+ {57, 1},
+};
+static const arc arcs_74_1[2] = {
+ {58, 2},
+ {0, 1},
+};
+static const arc arcs_74_2[1] = {
+ {0, 2},
+};
+static state states_74[3] = {
+ {1, arcs_74_0},
+ {2, arcs_74_1},
+ {1, arcs_74_2},
+};
+static const arc arcs_75_0[2] = {
+ {126, 1},
+ {84, 1},
+};
+static const arc arcs_75_1[2] = {
+ {65, 2},
+ {0, 1},
+};
+static const arc arcs_75_2[3] = {
+ {126, 1},
+ {84, 1},
+ {0, 2},
+};
+static state states_75[3] = {
+ {2, arcs_75_0},
+ {2, arcs_75_1},
+ {3, arcs_75_2},
+};
+static const arc arcs_76_0[1] = {
+ {58, 1},
+};
+static const arc arcs_76_1[2] = {
+ {65, 2},
+ {0, 1},
+};
+static const arc arcs_76_2[2] = {
+ {58, 1},
+ {0, 2},
+};
+static state states_76[3] = {
+ {1, arcs_76_0},
+ {2, arcs_76_1},
+ {2, arcs_76_2},
+};
+static const arc arcs_77_0[3] = {
+ {63, 1},
+ {84, 2},
+ {58, 3},
+};
+static const arc arcs_77_1[1] = {
+ {126, 4},
+};
+static const arc arcs_77_2[3] = {
+ {65, 5},
+ {169, 6},
+ {0, 2},
+};
+static const arc arcs_77_3[4] = {
+ {65, 5},
+ {57, 7},
+ {169, 6},
+ {0, 3},
+};
+static const arc arcs_77_4[3] = {
+ {65, 8},
+ {169, 6},
+ {0, 4},
+};
+static const arc arcs_77_5[3] = {
+ {84, 9},
+ {58, 9},
+ {0, 5},
+};
+static const arc arcs_77_6[1] = {
+ {0, 6},
+};
+static const arc arcs_77_7[1] = {
+ {58, 4},
+};
+static const arc arcs_77_8[3] = {
+ {63, 10},
+ {58, 11},
+ {0, 8},
+};
+static const arc arcs_77_9[2] = {
+ {65, 5},
+ {0, 9},
+};
+static const arc arcs_77_10[1] = {
+ {126, 12},
+};
+static const arc arcs_77_11[1] = {
+ {57, 13},
+};
+static const arc arcs_77_12[2] = {
+ {65, 8},
+ {0, 12},
+};
+static const arc arcs_77_13[1] = {
+ {58, 12},
+};
+static state states_77[14] = {
+ {3, arcs_77_0},
+ {1, arcs_77_1},
+ {3, arcs_77_2},
+ {4, arcs_77_3},
+ {3, arcs_77_4},
+ {3, arcs_77_5},
+ {1, arcs_77_6},
+ {1, arcs_77_7},
+ {3, arcs_77_8},
+ {2, arcs_77_9},
+ {1, arcs_77_10},
+ {1, arcs_77_11},
+ {2, arcs_77_12},
+ {1, arcs_77_13},
+};
+static const arc arcs_78_0[1] = {
+ {17, 1},
+};
+static const arc arcs_78_1[1] = {
+ {40, 2},
+};
+static const arc arcs_78_2[2] = {
+ {5, 3},
+ {57, 4},
+};
+static const arc arcs_78_3[2] = {
+ {61, 5},
+ {170, 6},
+};
+static const arc arcs_78_4[1] = {
+ {119, 7},
+};
+static const arc arcs_78_5[1] = {
+ {57, 4},
+};
+static const arc arcs_78_6[1] = {
+ {61, 5},
+};
+static const arc arcs_78_7[1] = {
+ {0, 7},
+};
+static state states_78[8] = {
+ {1, arcs_78_0},
+ {1, arcs_78_1},
+ {2, arcs_78_2},
+ {2, arcs_78_3},
+ {1, arcs_78_4},
+ {1, arcs_78_5},
+ {1, arcs_78_6},
+ {1, arcs_78_7},
+};
+static const arc arcs_79_0[1] = {
+ {174, 1},
+};
+static const arc arcs_79_1[2] = {
+ {65, 2},
+ {0, 1},
+};
+static const arc arcs_79_2[2] = {
+ {174, 1},
+ {0, 2},
+};
+static state states_79[3] = {
+ {1, arcs_79_0},
+ {2, arcs_79_1},
+ {2, arcs_79_2},
+};
+static const arc arcs_80_0[3] = {
+ {6, 1},
+ {63, 1},
+ {58, 2},
+};
+static const arc arcs_80_1[1] = {
+ {58, 3},
+};
+static const arc arcs_80_2[4] = {
+ {130, 1},
+ {66, 1},
+ {169, 3},
+ {0, 2},
+};
+static const arc arcs_80_3[1] = {
+ {0, 3},
+};
+static state states_80[4] = {
+ {3, arcs_80_0},
+ {1, arcs_80_1},
+ {4, arcs_80_2},
+ {1, arcs_80_3},
+};
+static const arc arcs_81_0[2] = {
+ {169, 1},
+ {176, 1},
+};
+static const arc arcs_81_1[1] = {
+ {0, 1},
+};
+static state states_81[2] = {
+ {2, arcs_81_0},
+ {1, arcs_81_1},
+};
+static const arc arcs_82_0[1] = {
+ {21, 1},
+};
+static const arc arcs_82_1[1] = {
+ {98, 2},
+};
+static const arc arcs_82_2[1] = {
+ {122, 3},
+};
+static const arc arcs_82_3[1] = {
+ {132, 4},
+};
+static const arc arcs_82_4[2] = {
+ {175, 5},
+ {0, 4},
+};
+static const arc arcs_82_5[1] = {
+ {0, 5},
+};
+static state states_82[6] = {
+ {1, arcs_82_0},
+ {1, arcs_82_1},
+ {1, arcs_82_2},
+ {1, arcs_82_3},
+ {2, arcs_82_4},
+ {1, arcs_82_5},
+};
+static const arc arcs_83_0[2] = {
+ {38, 1},
+ {177, 2},
+};
+static const arc arcs_83_1[1] = {
+ {177, 2},
+};
+static const arc arcs_83_2[1] = {
+ {0, 2},
+};
+static state states_83[3] = {
+ {2, arcs_83_0},
+ {1, arcs_83_1},
+ {1, arcs_83_2},
+};
+static const arc arcs_84_0[1] = {
+ {24, 1},
+};
+static const arc arcs_84_1[1] = {
+ {133, 2},
+};
+static const arc arcs_84_2[2] = {
+ {175, 3},
+ {0, 2},
+};
+static const arc arcs_84_3[1] = {
+ {0, 3},
+};
+static state states_84[4] = {
+ {1, arcs_84_0},
+ {1, arcs_84_1},
+ {2, arcs_84_2},
+ {1, arcs_84_3},
+};
+static const arc arcs_85_0[1] = {
+ {40, 1},
+};
+static const arc arcs_85_1[1] = {
+ {0, 1},
+};
+static state states_85[2] = {
+ {1, arcs_85_0},
+ {1, arcs_85_1},
+};
+static const arc arcs_86_0[1] = {
+ {35, 1},
+};
+static const arc arcs_86_1[2] = {
+ {179, 2},
+ {0, 1},
+};
+static const arc arcs_86_2[1] = {
+ {0, 2},
+};
+static state states_86[3] = {
+ {1, arcs_86_0},
+ {2, arcs_86_1},
+ {1, arcs_86_2},
+};
+static const arc arcs_87_0[2] = {
+ {22, 1},
+ {80, 2},
+};
+static const arc arcs_87_1[1] = {
+ {58, 2},
+};
+static const arc arcs_87_2[1] = {
+ {0, 2},
+};
+static state states_87[3] = {
+ {2, arcs_87_0},
+ {1, arcs_87_1},
+ {1, arcs_87_2},
+};
+static const arc arcs_88_0[2] = {
+ {2, 1},
+ {4, 2},
+};
+static const arc arcs_88_1[2] = {
+ {128, 3},
+ {59, 4},
+};
+static const arc arcs_88_2[1] = {
+ {0, 2},
+};
+static const arc arcs_88_3[1] = {
+ {45, 5},
+};
+static const arc arcs_88_4[1] = {
+ {2, 6},
+};
+static const arc arcs_88_5[2] = {
+ {129, 2},
+ {45, 5},
+};
+static const arc arcs_88_6[1] = {
+ {128, 3},
+};
+static state states_88[7] = {
+ {2, arcs_88_0},
+ {2, arcs_88_1},
+ {1, arcs_88_2},
+ {1, arcs_88_3},
+ {1, arcs_88_4},
+ {2, arcs_88_5},
+ {1, arcs_88_6},
+};
+static const arc arcs_89_0[1] = {
+ {181, 1},
+};
+static const arc arcs_89_1[2] = {
+ {44, 2},
+ {2, 1},
+};
+static const arc arcs_89_2[1] = {
+ {0, 2},
+};
+static state states_89[3] = {
+ {1, arcs_89_0},
+ {2, arcs_89_1},
+ {1, arcs_89_2},
+};
+static const arc arcs_90_0[1] = {
+ {5, 1},
+};
+static const arc arcs_90_1[2] = {
+ {61, 2},
+ {182, 3},
+};
+static const arc arcs_90_2[1] = {
+ {56, 4},
+};
+static const arc arcs_90_3[1] = {
+ {61, 2},
+};
+static const arc arcs_90_4[1] = {
+ {58, 5},
+};
+static const arc arcs_90_5[1] = {
+ {0, 5},
+};
+static state states_90[6] = {
+ {1, arcs_90_0},
+ {2, arcs_90_1},
+ {1, arcs_90_2},
+ {1, arcs_90_3},
+ {1, arcs_90_4},
+ {1, arcs_90_5},
+};
+static const arc arcs_91_0[3] = {
+ {6, 1},
+ {63, 2},
+ {58, 3},
+};
+static const arc arcs_91_1[3] = {
+ {65, 4},
+ {58, 5},
+ {0, 1},
+};
+static const arc arcs_91_2[1] = {
+ {58, 6},
+};
+static const arc arcs_91_3[2] = {
+ {65, 7},
+ {0, 3},
+};
+static const arc arcs_91_4[2] = {
+ {63, 2},
+ {58, 5},
+};
+static const arc arcs_91_5[2] = {
+ {65, 4},
+ {0, 5},
+};
+static const arc arcs_91_6[1] = {
+ {0, 6},
+};
+static const arc arcs_91_7[4] = {
+ {6, 8},
+ {63, 2},
+ {58, 3},
+ {0, 7},
+};
+static const arc arcs_91_8[3] = {
+ {65, 9},
+ {58, 10},
+ {0, 8},
+};
+static const arc arcs_91_9[2] = {
+ {63, 2},
+ {58, 10},
+};
+static const arc arcs_91_10[2] = {
+ {65, 9},
+ {0, 10},
+};
+static state states_91[11] = {
+ {3, arcs_91_0},
+ {3, arcs_91_1},
+ {1, arcs_91_2},
+ {2, arcs_91_3},
+ {2, arcs_91_4},
+ {2, arcs_91_5},
+ {1, arcs_91_6},
+ {4, arcs_91_7},
+ {3, arcs_91_8},
+ {2, arcs_91_9},
+ {2, arcs_91_10},
+};
+static const dfa dfas[92] = {
+ {256, "single_input", 3, states_0,
+ "\344\377\377\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {257, "file_input", 2, states_1,
+ "\344\377\377\377\377\027\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {258, "eval_input", 3, states_2,
+ "\240\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {259, "decorator", 4, states_3,
+ "\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {260, "decorators", 2, states_4,
+ "\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {261, "decorated", 3, states_5,
+ "\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {262, "async_funcdef", 3, states_6,
+ "\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {263, "funcdef", 9, states_7,
+ "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {264, "parameters", 4, states_8,
+ "\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {265, "typedargslist", 42, states_9,
+ "\100\000\000\000\000\001\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {266, "tfpdef", 4, states_10,
+ "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {267, "varargslist", 34, states_11,
+ "\100\000\000\000\000\001\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {268, "vfpdef", 2, states_12,
+ "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {269, "stmt", 2, states_13,
+ "\340\377\377\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {270, "simple_stmt", 4, states_14,
+ "\340\373\325\376\270\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {271, "small_stmt", 2, states_15,
+ "\340\373\325\376\270\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {272, "expr_stmt", 6, states_16,
+ "\340\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {273, "annassign", 5, states_17,
+ "\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {274, "testlist_star_expr", 3, states_18,
+ "\340\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {275, "augassign", 2, states_19,
+ "\000\000\000\000\000\000\000\000\000\000\340\377\003\000\000\000\000\000\000\000\000\000\000"},
+ {276, "del_stmt", 3, states_20,
+ "\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {277, "pass_stmt", 2, states_21,
+ "\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {278, "flow_stmt", 2, states_22,
+ "\000\000\005\300\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {279, "break_stmt", 2, states_23,
+ "\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {280, "continue_stmt", 2, states_24,
+ "\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {281, "return_stmt", 3, states_25,
+ "\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {282, "yield_stmt", 2, states_26,
+ "\000\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {283, "raise_stmt", 5, states_27,
+ "\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {284, "import_stmt", 2, states_28,
+ "\000\000\100\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {285, "import_name", 3, states_29,
+ "\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {286, "import_from", 8, states_30,
+ "\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {287, "import_as_name", 4, states_31,
+ "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {288, "dotted_as_name", 4, states_32,
+ "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {289, "import_as_names", 3, states_33,
+ "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {290, "dotted_as_names", 2, states_34,
+ "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {291, "dotted_name", 2, states_35,
+ "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {292, "global_stmt", 3, states_36,
+ "\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {293, "nonlocal_stmt", 3, states_37,
+ "\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {294, "assert_stmt", 5, states_38,
+ "\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {295, "compound_stmt", 2, states_39,
+ "\000\004\052\001\107\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {296, "async_stmt", 3, states_40,
+ "\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {297, "if_stmt", 8, states_41,
+ "\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {298, "while_stmt", 8, states_42,
+ "\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {299, "for_stmt", 11, states_43,
+ "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {300, "try_stmt", 13, states_44,
+ "\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {301, "with_stmt", 6, states_45,
+ "\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {302, "with_item", 4, states_46,
+ "\240\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {303, "except_clause", 5, states_47,
+ "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000"},
+ {304, "suite", 5, states_48,
+ "\344\373\325\376\270\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {305, "namedexpr_test", 4, states_49,
+ "\240\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {306, "test", 6, states_50,
+ "\240\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {307, "test_nocond", 2, states_51,
+ "\240\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {308, "lambdef", 5, states_52,
+ "\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {309, "lambdef_nocond", 5, states_53,
+ "\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {310, "or_test", 2, states_54,
+ "\240\173\000\020\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {311, "and_test", 2, states_55,
+ "\240\173\000\020\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {312, "not_test", 3, states_56,
+ "\240\173\000\020\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {313, "comparison", 2, states_57,
+ "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {314, "comp_op", 4, states_58,
+ "\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\004\000\340\017\000\000\000\000"},
+ {315, "star_expr", 3, states_59,
+ "\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {316, "expr", 2, states_60,
+ "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {317, "xor_expr", 2, states_61,
+ "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {318, "and_expr", 2, states_62,
+ "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {319, "shift_expr", 2, states_63,
+ "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {320, "arith_expr", 2, states_64,
+ "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {321, "term", 2, states_65,
+ "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {322, "factor", 3, states_66,
+ "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {323, "power", 4, states_67,
+ "\040\172\000\000\220\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {324, "atom_expr", 3, states_68,
+ "\040\172\000\000\220\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {325, "atom", 9, states_69,
+ "\040\172\000\000\020\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {326, "testlist_comp", 5, states_70,
+ "\340\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {327, "trailer", 7, states_71,
+ "\040\100\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000"},
+ {328, "subscriptlist", 3, states_72,
+ "\240\173\000\024\260\007\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {329, "subscript", 5, states_73,
+ "\240\173\000\024\260\007\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {330, "sliceop", 3, states_74,
+ "\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {331, "exprlist", 3, states_75,
+ "\340\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {332, "testlist", 3, states_76,
+ "\240\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {333, "dictorsetmaker", 14, states_77,
+ "\340\173\000\024\260\007\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {334, "classdef", 8, states_78,
+ "\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {335, "arglist", 3, states_79,
+ "\340\173\000\024\260\007\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {336, "argument", 4, states_80,
+ "\340\173\000\024\260\007\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {337, "comp_iter", 2, states_81,
+ "\000\000\040\001\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {338, "sync_comp_for", 6, states_82,
+ "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {339, "comp_for", 3, states_83,
+ "\000\000\040\000\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {340, "comp_if", 4, states_84,
+ "\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {341, "encoding_decl", 2, states_85,
+ "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {342, "yield_expr", 3, states_86,
+ "\000\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {343, "yield_arg", 3, states_87,
+ "\340\173\100\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {344, "func_body_suite", 7, states_88,
+ "\344\373\325\376\270\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {345, "func_type_input", 3, states_89,
+ "\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {346, "func_type", 6, states_90,
+ "\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {347, "typelist", 11, states_91,
+ "\340\173\000\024\260\007\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+};
+static const label labels[183] = {
+ {0, "EMPTY"},
+ {256, 0},
+ {4, 0},
+ {295, 0},
+ {270, 0},
+ {7, 0},
+ {16, 0},
+ {14, 0},
+ {15, 0},
+ {52, 0},
+ {49, 0},
+ {1, "False"},
+ {1, "None"},
+ {1, "True"},
+ {9, 0},
+ {1, "assert"},
+ {1, "break"},
+ {1, "class"},
+ {1, "continue"},
+ {1, "def"},
+ {1, "del"},
+ {1, "for"},
+ {1, "from"},
+ {1, "global"},
+ {1, "if"},
+ {1, "import"},
+ {1, "lambda"},
+ {1, "nonlocal"},
+ {1, "not"},
+ {1, "pass"},
+ {1, "raise"},
+ {1, "return"},
+ {1, "try"},
+ {1, "while"},
+ {1, "with"},
+ {1, "yield"},
+ {25, 0},
+ {31, 0},
+ {56, 0},
+ {55, 0},
+ {1, 0},
+ {2, 0},
+ {3, 0},
+ {257, 0},
+ {0, 0},
+ {269, 0},
+ {258, 0},
+ {332, 0},
+ {259, 0},
+ {305, 0},
+ {260, 0},
+ {261, 0},
+ {262, 0},
+ {334, 0},
+ {263, 0},
+ {264, 0},
+ {51, 0},
+ {11, 0},
+ {306, 0},
+ {58, 0},
+ {344, 0},
+ {8, 0},
+ {265, 0},
+ {35, 0},
+ {266, 0},
+ {12, 0},
+ {22, 0},
+ {17, 0},
+ {267, 0},
+ {268, 0},
+ {271, 0},
+ {13, 0},
+ {294, 0},
+ {276, 0},
+ {272, 0},
+ {278, 0},
+ {292, 0},
+ {284, 0},
+ {293, 0},
+ {277, 0},
+ {274, 0},
+ {273, 0},
+ {275, 0},
+ {342, 0},
+ {315, 0},
+ {40, 0},
+ {41, 0},
+ {46, 0},
+ {38, 0},
+ {36, 0},
+ {37, 0},
+ {48, 0},
+ {39, 0},
+ {44, 0},
+ {45, 0},
+ {50, 0},
+ {43, 0},
+ {42, 0},
+ {331, 0},
+ {279, 0},
+ {280, 0},
+ {283, 0},
+ {281, 0},
+ {282, 0},
+ {286, 0},
+ {285, 0},
+ {290, 0},
+ {23, 0},
+ {291, 0},
+ {289, 0},
+ {287, 0},
+ {1, "as"},
+ {288, 0},
+ {296, 0},
+ {299, 0},
+ {297, 0},
+ {300, 0},
+ {298, 0},
+ {301, 0},
+ {304, 0},
+ {1, "elif"},
+ {1, "else"},
+ {1, "in"},
+ {1, "finally"},
+ {303, 0},
+ {302, 0},
+ {316, 0},
+ {1, "except"},
+ {5, 0},
+ {6, 0},
+ {53, 0},
+ {308, 0},
+ {310, 0},
+ {307, 0},
+ {309, 0},
+ {311, 0},
+ {1, "or"},
+ {312, 0},
+ {1, "and"},
+ {313, 0},
+ {314, 0},
+ {28, 0},
+ {20, 0},
+ {29, 0},
+ {27, 0},
+ {21, 0},
+ {30, 0},
+ {1, "is"},
+ {317, 0},
+ {18, 0},
+ {318, 0},
+ {32, 0},
+ {319, 0},
+ {19, 0},
+ {320, 0},
+ {33, 0},
+ {34, 0},
+ {321, 0},
+ {322, 0},
+ {24, 0},
+ {47, 0},
+ {323, 0},
+ {324, 0},
+ {325, 0},
+ {327, 0},
+ {326, 0},
+ {10, 0},
+ {26, 0},
+ {333, 0},
+ {339, 0},
+ {335, 0},
+ {328, 0},
+ {329, 0},
+ {330, 0},
+ {336, 0},
+ {337, 0},
+ {340, 0},
+ {338, 0},
+ {341, 0},
+ {343, 0},
+ {345, 0},
+ {346, 0},
+ {347, 0},
+};
+Py_EXPORTED_SYMBOL grammar _PyParser_Grammar = {
+ 92,
+ dfas,
+ {183, labels},
+ 256
+};
diff --git a/contrib/tools/python3/src/Python/hamt.c b/contrib/tools/python3/src/Python/hamt.c
new file mode 100644
index 00000000000..8801c5ea418
--- /dev/null
+++ b/contrib/tools/python3/src/Python/hamt.c
@@ -0,0 +1,2996 @@
+#include "Python.h"
+
+#include "pycore_hamt.h"
+#include "pycore_object.h" // _PyObject_GC_TRACK()
+#include <stddef.h> // offsetof()
+
+/*
+This file provides an implementation of an immutable mapping using the
+Hash Array Mapped Trie (or HAMT) datastructure.
+
+This design allows to have:
+
+1. Efficient copy: immutable mappings can be copied by reference,
+ making it an O(1) operation.
+
+2. Efficient mutations: due to structural sharing, only a portion of
+ the trie needs to be copied when the collection is mutated. The
+ cost of set/delete operations is O(log N).
+
+3. Efficient lookups: O(log N).
+
+(where N is number of key/value items in the immutable mapping.)
+
+
+HAMT
+====
+
+The core idea of HAMT is that the shape of the trie is encoded into the
+hashes of keys.
+
+Say we want to store a K/V pair in our mapping. First, we calculate the
+hash of K, let's say it's 19830128, or in binary:
+
+ 0b1001011101001010101110000 = 19830128
+
+Now let's partition this bit representation of the hash into blocks of
+5 bits each:
+
+ 0b00_00000_10010_11101_00101_01011_10000 = 19830128
+ (6) (5) (4) (3) (2) (1)
+
+Each block of 5 bits represents a number between 0 and 31. So if we have
+a tree that consists of nodes, each of which is an array of 32 pointers,
+those 5-bit blocks will encode a position on a single tree level.
+
+For example, storing the key K with hash 19830128, results in the following
+tree structure:
+
+ (array of 32 pointers)
+ +---+ -- +----+----+----+ -- +----+
+ root node | 0 | .. | 15 | 16 | 17 | .. | 31 | 0b10000 = 16 (1)
+ (level 1) +---+ -- +----+----+----+ -- +----+
+ |
+ +---+ -- +----+----+----+ -- +----+
+ a 2nd level node | 0 | .. | 10 | 11 | 12 | .. | 31 | 0b01011 = 11 (2)
+ +---+ -- +----+----+----+ -- +----+
+ |
+ +---+ -- +----+----+----+ -- +----+
+ a 3rd level node | 0 | .. | 04 | 05 | 06 | .. | 31 | 0b00101 = 5 (3)
+ +---+ -- +----+----+----+ -- +----+
+ |
+ +---+ -- +----+----+----+----+
+ a 4th level node | 0 | .. | 04 | 29 | 30 | 31 | 0b11101 = 29 (4)
+ +---+ -- +----+----+----+----+
+ |
+ +---+ -- +----+----+----+ -- +----+
+ a 5th level node | 0 | .. | 17 | 18 | 19 | .. | 31 | 0b10010 = 18 (5)
+ +---+ -- +----+----+----+ -- +----+
+ |
+ +--------------+
+ |
+ +---+ -- +----+----+----+ -- +----+
+ a 6th level node | 0 | .. | 15 | 16 | 17 | .. | 31 | 0b00000 = 0 (6)
+ +---+ -- +----+----+----+ -- +----+
+ |
+ V -- our value (or collision)
+
+To rehash: for a K/V pair, the hash of K encodes where in the tree V will
+be stored.
+
+To optimize memory footprint and handle hash collisions, our implementation
+uses three different types of nodes:
+
+ * A Bitmap node;
+ * An Array node;
+ * A Collision node.
+
+Because we implement an immutable dictionary, our nodes are also
+immutable. Therefore, when we need to modify a node, we copy it, and
+do that modification to the copy.
+
+
+Array Nodes
+-----------
+
+These nodes are very simple. Essentially they are arrays of 32 pointers
+we used to illustrate the high-level idea in the previous section.
+
+We use Array nodes only when we need to store more than 16 pointers
+in a single node.
+
+Array nodes do not store key objects or value objects. They are used
+only as an indirection level - their pointers point to other nodes in
+the tree.
+
+
+Bitmap Node
+-----------
+
+Allocating a new 32-pointers array for every node of our tree would be
+very expensive. Unless we store millions of keys, most of tree nodes would
+be very sparse.
+
+When we have less than 16 elements in a node, we don't want to use the
+Array node, that would mean that we waste a lot of memory. Instead,
+we can use bitmap compression and can have just as many pointers
+as we need!
+
+Bitmap nodes consist of two fields:
+
+1. An array of pointers. If a Bitmap node holds N elements, the
+ array will be of N pointers.
+
+2. A 32bit integer -- a bitmap field. If an N-th bit is set in the
+ bitmap, it means that the node has an N-th element.
+
+For example, say we need to store a 3 elements sparse array:
+
+ +---+ -- +---+ -- +----+ -- +----+
+ | 0 | .. | 4 | .. | 11 | .. | 17 |
+ +---+ -- +---+ -- +----+ -- +----+
+ | | |
+ o1 o2 o3
+
+We allocate a three-pointer Bitmap node. Its bitmap field will be
+then set to:
+
+ 0b_00100_00010_00000_10000 == (1 << 17) | (1 << 11) | (1 << 4)
+
+To check if our Bitmap node has an I-th element we can do:
+
+ bitmap & (1 << I)
+
+
+And here's a formula to calculate a position in our pointer array
+which would correspond to an I-th element:
+
+ popcount(bitmap & ((1 << I) - 1))
+
+
+Let's break it down:
+
+ * `popcount` is a function that returns a number of bits set to 1;
+
+ * `((1 << I) - 1)` is a mask to filter the bitmask to contain bits
+ set to the *right* of our bit.
+
+
+So for our 17, 11, and 4 indexes:
+
+ * bitmap & ((1 << 17) - 1) == 0b100000010000 => 2 bits are set => index is 2.
+
+ * bitmap & ((1 << 11) - 1) == 0b10000 => 1 bit is set => index is 1.
+
+ * bitmap & ((1 << 4) - 1) == 0b0 => 0 bits are set => index is 0.
+
+
+To conclude: Bitmap nodes are just like Array nodes -- they can store
+a number of pointers, but use bitmap compression to eliminate unused
+pointers.
+
+
+Bitmap nodes have two pointers for each item:
+
+ +----+----+----+----+ -- +----+----+
+ | k1 | v1 | k2 | v2 | .. | kN | vN |
+ +----+----+----+----+ -- +----+----+
+
+When kI == NULL, vI points to another tree level.
+
+When kI != NULL, the actual key object is stored in kI, and its
+value is stored in vI.
+
+
+Collision Nodes
+---------------
+
+Collision nodes are simple arrays of pointers -- two pointers per
+key/value. When there's a hash collision, say for k1/v1 and k2/v2
+we have `hash(k1)==hash(k2)`. Then our collision node will be:
+
+ +----+----+----+----+
+ | k1 | v1 | k2 | v2 |
+ +----+----+----+----+
+
+
+Tree Structure
+--------------
+
+All nodes are PyObjects.
+
+The `PyHamtObject` object has a pointer to the root node (h_root),
+and has a length field (h_count).
+
+High-level functions accept a PyHamtObject object and dispatch to
+lower-level functions depending on what kind of node h_root points to.
+
+
+Operations
+==========
+
+There are three fundamental operations on an immutable dictionary:
+
+1. "o.assoc(k, v)" will return a new immutable dictionary, that will be
+ a copy of "o", but with the "k/v" item set.
+
+ Functions in this file:
+
+ hamt_node_assoc, hamt_node_bitmap_assoc,
+ hamt_node_array_assoc, hamt_node_collision_assoc
+
+ `hamt_node_assoc` function accepts a node object, and calls
+ other functions depending on its actual type.
+
+2. "o.find(k)" will lookup key "k" in "o".
+
+ Functions:
+
+ hamt_node_find, hamt_node_bitmap_find,
+ hamt_node_array_find, hamt_node_collision_find
+
+3. "o.without(k)" will return a new immutable dictionary, that will be
+ a copy of "o", buth without the "k" key.
+
+ Functions:
+
+ hamt_node_without, hamt_node_bitmap_without,
+ hamt_node_array_without, hamt_node_collision_without
+
+
+Further Reading
+===============
+
+1. http://blog.higher-order.net/2009/09/08/understanding-clojures-persistenthashmap-deftwice.html
+
+2. http://blog.higher-order.net/2010/08/16/assoc-and-clojures-persistenthashmap-part-ii.html
+
+3. Clojure's PersistentHashMap implementation:
+ https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentHashMap.java
+
+
+Debug
+=====
+
+The HAMT datatype is accessible for testing purposes under the
+`_testcapi` module:
+
+ >>> from _testcapi import hamt
+ >>> h = hamt()
+ >>> h2 = h.set('a', 2)
+ >>> h3 = h2.set('b', 3)
+ >>> list(h3)
+ ['a', 'b']
+
+When CPython is built in debug mode, a '__dump__()' method is available
+to introspect the tree:
+
+ >>> print(h3.__dump__())
+ HAMT(len=2):
+ BitmapNode(size=4 count=2 bitmap=0b110 id=0x10eb9d9e8):
+ 'a': 2
+ 'b': 3
+*/
+
+
+#define IS_ARRAY_NODE(node) Py_IS_TYPE(node, &_PyHamt_ArrayNode_Type)
+#define IS_BITMAP_NODE(node) Py_IS_TYPE(node, &_PyHamt_BitmapNode_Type)
+#define IS_COLLISION_NODE(node) Py_IS_TYPE(node, &_PyHamt_CollisionNode_Type)
+
+
+/* Return type for 'find' (lookup a key) functions.
+
+ * F_ERROR - an error occurred;
+ * F_NOT_FOUND - the key was not found;
+ * F_FOUND - the key was found.
+*/
+typedef enum {F_ERROR, F_NOT_FOUND, F_FOUND} hamt_find_t;
+
+
+/* Return type for 'without' (delete a key) functions.
+
+ * W_ERROR - an error occurred;
+ * W_NOT_FOUND - the key was not found: there's nothing to delete;
+ * W_EMPTY - the key was found: the node/tree would be empty
+ if the key is deleted;
+ * W_NEWNODE - the key was found: a new node/tree is returned
+ without that key.
+*/
+typedef enum {W_ERROR, W_NOT_FOUND, W_EMPTY, W_NEWNODE} hamt_without_t;
+
+
+/* Low-level iterator protocol type.
+
+ * I_ITEM - a new item has been yielded;
+ * I_END - the whole tree was visited (similar to StopIteration).
+*/
+typedef enum {I_ITEM, I_END} hamt_iter_t;
+
+
+#define HAMT_ARRAY_NODE_SIZE 32
+
+
+typedef struct {
+ PyObject_HEAD
+ PyHamtNode *a_array[HAMT_ARRAY_NODE_SIZE];
+ Py_ssize_t a_count;
+} PyHamtNode_Array;
+
+
+typedef struct {
+ PyObject_VAR_HEAD
+ uint32_t b_bitmap;
+ PyObject *b_array[1];
+} PyHamtNode_Bitmap;
+
+
+typedef struct {
+ PyObject_VAR_HEAD
+ int32_t c_hash;
+ PyObject *c_array[1];
+} PyHamtNode_Collision;
+
+
+static PyHamtNode_Bitmap *_empty_bitmap_node;
+static PyHamtObject *_empty_hamt;
+
+
+static PyHamtObject *
+hamt_alloc(void);
+
+static PyHamtNode *
+hamt_node_assoc(PyHamtNode *node,
+ uint32_t shift, int32_t hash,
+ PyObject *key, PyObject *val, int* added_leaf);
+
+static hamt_without_t
+hamt_node_without(PyHamtNode *node,
+ uint32_t shift, int32_t hash,
+ PyObject *key,
+ PyHamtNode **new_node);
+
+static hamt_find_t
+hamt_node_find(PyHamtNode *node,
+ uint32_t shift, int32_t hash,
+ PyObject *key, PyObject **val);
+
+#ifdef Py_DEBUG
+static int
+hamt_node_dump(PyHamtNode *node,
+ _PyUnicodeWriter *writer, int level);
+#endif
+
+static PyHamtNode *
+hamt_node_array_new(Py_ssize_t);
+
+static PyHamtNode *
+hamt_node_collision_new(int32_t hash, Py_ssize_t size);
+
+static inline Py_ssize_t
+hamt_node_collision_count(PyHamtNode_Collision *node);
+
+
+#ifdef Py_DEBUG
+static void
+_hamt_node_array_validate(void *obj_raw)
+{
+ PyObject *obj = _PyObject_CAST(obj_raw);
+ assert(IS_ARRAY_NODE(obj));
+ PyHamtNode_Array *node = (PyHamtNode_Array*)obj;
+ Py_ssize_t i = 0, count = 0;
+ for (; i < HAMT_ARRAY_NODE_SIZE; i++) {
+ if (node->a_array[i] != NULL) {
+ count++;
+ }
+ }
+ assert(count == node->a_count);
+}
+
+#define VALIDATE_ARRAY_NODE(NODE) \
+ do { _hamt_node_array_validate(NODE); } while (0);
+#else
+#define VALIDATE_ARRAY_NODE(NODE)
+#endif
+
+
+/* Returns -1 on error */
+static inline int32_t
+hamt_hash(PyObject *o)
+{
+ Py_hash_t hash = PyObject_Hash(o);
+
+#if SIZEOF_PY_HASH_T <= 4
+ return hash;
+#else
+ if (hash == -1) {
+ /* exception */
+ return -1;
+ }
+
+ /* While it's suboptimal to reduce Python's 64 bit hash to
+ 32 bits via XOR, it seems that the resulting hash function
+ is good enough (this is also how Long type is hashed in Java.)
+ Storing 10, 100, 1000 Python strings results in a relatively
+ shallow and uniform tree structure.
+
+ Please don't change this hashing algorithm, as there are many
+ tests that test some exact tree shape to cover all code paths.
+ */
+ int32_t xored = (int32_t)(hash & 0xffffffffl) ^ (int32_t)(hash >> 32);
+ return xored == -1 ? -2 : xored;
+#endif
+}
+
+static inline uint32_t
+hamt_mask(int32_t hash, uint32_t shift)
+{
+ return (((uint32_t)hash >> shift) & 0x01f);
+}
+
+static inline uint32_t
+hamt_bitpos(int32_t hash, uint32_t shift)
+{
+ return (uint32_t)1 << hamt_mask(hash, shift);
+}
+
+static inline uint32_t
+hamt_bitcount(uint32_t i)
+{
+ /* We could use native popcount instruction but that would
+ require to either add configure flags to enable SSE4.2
+ support or to detect it dynamically. Otherwise, we have
+ a risk of CPython not working properly on older hardware.
+
+ In practice, there's no observable difference in
+ performance between using a popcount instruction or the
+ following fallback code.
+
+ The algorithm is copied from:
+ https://graphics.stanford.edu/~seander/bithacks.html
+ */
+ i = i - ((i >> 1) & 0x55555555);
+ i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
+ return (((i + (i >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
+}
+
+static inline uint32_t
+hamt_bitindex(uint32_t bitmap, uint32_t bit)
+{
+ return hamt_bitcount(bitmap & (bit - 1));
+}
+
+
+/////////////////////////////////// Dump Helpers
+#ifdef Py_DEBUG
+
+static int
+_hamt_dump_ident(_PyUnicodeWriter *writer, int level)
+{
+ /* Write `' ' * level` to the `writer` */
+ PyObject *str = NULL;
+ PyObject *num = NULL;
+ PyObject *res = NULL;
+ int ret = -1;
+
+ str = PyUnicode_FromString(" ");
+ if (str == NULL) {
+ goto error;
+ }
+
+ num = PyLong_FromLong((long)level);
+ if (num == NULL) {
+ goto error;
+ }
+
+ res = PyNumber_Multiply(str, num);
+ if (res == NULL) {
+ goto error;
+ }
+
+ ret = _PyUnicodeWriter_WriteStr(writer, res);
+
+error:
+ Py_XDECREF(res);
+ Py_XDECREF(str);
+ Py_XDECREF(num);
+ return ret;
+}
+
+static int
+_hamt_dump_format(_PyUnicodeWriter *writer, const char *format, ...)
+{
+ /* A convenient helper combining _PyUnicodeWriter_WriteStr and
+ PyUnicode_FromFormatV.
+ */
+ PyObject* msg;
+ int ret;
+
+ va_list vargs;
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, format);
+#else
+ va_start(vargs);
+#endif
+ msg = PyUnicode_FromFormatV(format, vargs);
+ va_end(vargs);
+
+ if (msg == NULL) {
+ return -1;
+ }
+
+ ret = _PyUnicodeWriter_WriteStr(writer, msg);
+ Py_DECREF(msg);
+ return ret;
+}
+
+#endif /* Py_DEBUG */
+/////////////////////////////////// Bitmap Node
+
+
+static PyHamtNode *
+hamt_node_bitmap_new(Py_ssize_t size)
+{
+ /* Create a new bitmap node of size 'size' */
+
+ PyHamtNode_Bitmap *node;
+ Py_ssize_t i;
+
+ assert(size >= 0);
+ assert(size % 2 == 0);
+
+ if (size == 0 && _empty_bitmap_node != NULL) {
+ Py_INCREF(_empty_bitmap_node);
+ return (PyHamtNode *)_empty_bitmap_node;
+ }
+
+ /* No freelist; allocate a new bitmap node */
+ node = PyObject_GC_NewVar(
+ PyHamtNode_Bitmap, &_PyHamt_BitmapNode_Type, size);
+ if (node == NULL) {
+ return NULL;
+ }
+
+ Py_SET_SIZE(node, size);
+
+ for (i = 0; i < size; i++) {
+ node->b_array[i] = NULL;
+ }
+
+ node->b_bitmap = 0;
+
+ _PyObject_GC_TRACK(node);
+
+ if (size == 0 && _empty_bitmap_node == NULL) {
+ /* Since bitmap nodes are immutable, we can cache the instance
+ for size=0 and reuse it whenever we need an empty bitmap node.
+ */
+ _empty_bitmap_node = node;
+ Py_INCREF(_empty_bitmap_node);
+ }
+
+ return (PyHamtNode *)node;
+}
+
+static inline Py_ssize_t
+hamt_node_bitmap_count(PyHamtNode_Bitmap *node)
+{
+ return Py_SIZE(node) / 2;
+}
+
+static PyHamtNode_Bitmap *
+hamt_node_bitmap_clone(PyHamtNode_Bitmap *node)
+{
+ /* Clone a bitmap node; return a new one with the same child notes. */
+
+ PyHamtNode_Bitmap *clone;
+ Py_ssize_t i;
+
+ clone = (PyHamtNode_Bitmap *)hamt_node_bitmap_new(Py_SIZE(node));
+ if (clone == NULL) {
+ return NULL;
+ }
+
+ for (i = 0; i < Py_SIZE(node); i++) {
+ Py_XINCREF(node->b_array[i]);
+ clone->b_array[i] = node->b_array[i];
+ }
+
+ clone->b_bitmap = node->b_bitmap;
+ return clone;
+}
+
+static PyHamtNode_Bitmap *
+hamt_node_bitmap_clone_without(PyHamtNode_Bitmap *o, uint32_t bit)
+{
+ assert(bit & o->b_bitmap);
+ assert(hamt_node_bitmap_count(o) > 1);
+
+ PyHamtNode_Bitmap *new = (PyHamtNode_Bitmap *)hamt_node_bitmap_new(
+ Py_SIZE(o) - 2);
+ if (new == NULL) {
+ return NULL;
+ }
+
+ uint32_t idx = hamt_bitindex(o->b_bitmap, bit);
+ uint32_t key_idx = 2 * idx;
+ uint32_t val_idx = key_idx + 1;
+ uint32_t i;
+
+ for (i = 0; i < key_idx; i++) {
+ Py_XINCREF(o->b_array[i]);
+ new->b_array[i] = o->b_array[i];
+ }
+
+ assert(Py_SIZE(o) >= 0 && Py_SIZE(o) <= 32);
+ for (i = val_idx + 1; i < (uint32_t)Py_SIZE(o); i++) {
+ Py_XINCREF(o->b_array[i]);
+ new->b_array[i - 2] = o->b_array[i];
+ }
+
+ new->b_bitmap = o->b_bitmap & ~bit;
+ return new;
+}
+
+static PyHamtNode *
+hamt_node_new_bitmap_or_collision(uint32_t shift,
+ PyObject *key1, PyObject *val1,
+ int32_t key2_hash,
+ PyObject *key2, PyObject *val2)
+{
+ /* Helper method. Creates a new node for key1/val and key2/val2
+ pairs.
+
+ If key1 hash is equal to the hash of key2, a Collision node
+ will be created. If they are not equal, a Bitmap node is
+ created.
+ */
+
+ int32_t key1_hash = hamt_hash(key1);
+ if (key1_hash == -1) {
+ return NULL;
+ }
+
+ if (key1_hash == key2_hash) {
+ PyHamtNode_Collision *n;
+ n = (PyHamtNode_Collision *)hamt_node_collision_new(key1_hash, 4);
+ if (n == NULL) {
+ return NULL;
+ }
+
+ Py_INCREF(key1);
+ n->c_array[0] = key1;
+ Py_INCREF(val1);
+ n->c_array[1] = val1;
+
+ Py_INCREF(key2);
+ n->c_array[2] = key2;
+ Py_INCREF(val2);
+ n->c_array[3] = val2;
+
+ return (PyHamtNode *)n;
+ }
+ else {
+ int added_leaf = 0;
+ PyHamtNode *n = hamt_node_bitmap_new(0);
+ if (n == NULL) {
+ return NULL;
+ }
+
+ PyHamtNode *n2 = hamt_node_assoc(
+ n, shift, key1_hash, key1, val1, &added_leaf);
+ Py_DECREF(n);
+ if (n2 == NULL) {
+ return NULL;
+ }
+
+ n = hamt_node_assoc(n2, shift, key2_hash, key2, val2, &added_leaf);
+ Py_DECREF(n2);
+ if (n == NULL) {
+ return NULL;
+ }
+
+ return n;
+ }
+}
+
+static PyHamtNode *
+hamt_node_bitmap_assoc(PyHamtNode_Bitmap *self,
+ uint32_t shift, int32_t hash,
+ PyObject *key, PyObject *val, int* added_leaf)
+{
+ /* assoc operation for bitmap nodes.
+
+ Return: a new node, or self if key/val already is in the
+ collection.
+
+ 'added_leaf' is later used in '_PyHamt_Assoc' to determine if
+ `hamt.set(key, val)` increased the size of the collection.
+ */
+
+ uint32_t bit = hamt_bitpos(hash, shift);
+ uint32_t idx = hamt_bitindex(self->b_bitmap, bit);
+
+ /* Bitmap node layout:
+
+ +------+------+------+------+ --- +------+------+
+ | key1 | val1 | key2 | val2 | ... | keyN | valN |
+ +------+------+------+------+ --- +------+------+
+ where `N < Py_SIZE(node)`.
+
+ The `node->b_bitmap` field is a bitmap. For a given
+ `(shift, hash)` pair we can determine:
+
+ - If this node has the corresponding key/val slots.
+ - The index of key/val slots.
+ */
+
+ if (self->b_bitmap & bit) {
+ /* The key is set in this node */
+
+ uint32_t key_idx = 2 * idx;
+ uint32_t val_idx = key_idx + 1;
+
+ assert(val_idx < (size_t)Py_SIZE(self));
+
+ PyObject *key_or_null = self->b_array[key_idx];
+ PyObject *val_or_node = self->b_array[val_idx];
+
+ if (key_or_null == NULL) {
+ /* key is NULL. This means that we have a few keys
+ that have the same (hash, shift) pair. */
+
+ assert(val_or_node != NULL);
+
+ PyHamtNode *sub_node = hamt_node_assoc(
+ (PyHamtNode *)val_or_node,
+ shift + 5, hash, key, val, added_leaf);
+ if (sub_node == NULL) {
+ return NULL;
+ }
+
+ if (val_or_node == (PyObject *)sub_node) {
+ Py_DECREF(sub_node);
+ Py_INCREF(self);
+ return (PyHamtNode *)self;
+ }
+
+ PyHamtNode_Bitmap *ret = hamt_node_bitmap_clone(self);
+ if (ret == NULL) {
+ return NULL;
+ }
+ Py_SETREF(ret->b_array[val_idx], (PyObject*)sub_node);
+ return (PyHamtNode *)ret;
+ }
+
+ assert(key != NULL);
+ /* key is not NULL. This means that we have only one other
+ key in this collection that matches our hash for this shift. */
+
+ int comp_err = PyObject_RichCompareBool(key, key_or_null, Py_EQ);
+ if (comp_err < 0) { /* exception in __eq__ */
+ return NULL;
+ }
+ if (comp_err == 1) { /* key == key_or_null */
+ if (val == val_or_node) {
+ /* we already have the same key/val pair; return self. */
+ Py_INCREF(self);
+ return (PyHamtNode *)self;
+ }
+
+ /* We're setting a new value for the key we had before.
+ Make a new bitmap node with a replaced value, and return it. */
+ PyHamtNode_Bitmap *ret = hamt_node_bitmap_clone(self);
+ if (ret == NULL) {
+ return NULL;
+ }
+ Py_INCREF(val);
+ Py_SETREF(ret->b_array[val_idx], val);
+ return (PyHamtNode *)ret;
+ }
+
+ /* It's a new key, and it has the same index as *one* another key.
+ We have a collision. We need to create a new node which will
+ combine the existing key and the key we're adding.
+
+ `hamt_node_new_bitmap_or_collision` will either create a new
+ Collision node if the keys have identical hashes, or
+ a new Bitmap node.
+ */
+ PyHamtNode *sub_node = hamt_node_new_bitmap_or_collision(
+ shift + 5,
+ key_or_null, val_or_node, /* existing key/val */
+ hash,
+ key, val /* new key/val */
+ );
+ if (sub_node == NULL) {
+ return NULL;
+ }
+
+ PyHamtNode_Bitmap *ret = hamt_node_bitmap_clone(self);
+ if (ret == NULL) {
+ Py_DECREF(sub_node);
+ return NULL;
+ }
+ Py_SETREF(ret->b_array[key_idx], NULL);
+ Py_SETREF(ret->b_array[val_idx], (PyObject *)sub_node);
+
+ *added_leaf = 1;
+ return (PyHamtNode *)ret;
+ }
+ else {
+ /* There was no key before with the same (shift,hash). */
+
+ uint32_t n = hamt_bitcount(self->b_bitmap);
+
+ if (n >= 16) {
+ /* When we have a situation where we want to store more
+ than 16 nodes at one level of the tree, we no longer
+ want to use the Bitmap node with bitmap encoding.
+
+ Instead we start using an Array node, which has
+ simpler (faster) implementation at the expense of
+ having preallocated 32 pointers for its keys/values
+ pairs.
+
+ Small hamt objects (<30 keys) usually don't have any
+ Array nodes at all. Between ~30 and ~400 keys hamt
+ objects usually have one Array node, and usually it's
+ a root node.
+ */
+
+ uint32_t jdx = hamt_mask(hash, shift);
+ /* 'jdx' is the index of where the new key should be added
+ in the new Array node we're about to create. */
+
+ PyHamtNode *empty = NULL;
+ PyHamtNode_Array *new_node = NULL;
+ PyHamtNode *res = NULL;
+
+ /* Create a new Array node. */
+ new_node = (PyHamtNode_Array *)hamt_node_array_new(n + 1);
+ if (new_node == NULL) {
+ goto fin;
+ }
+
+ /* Create an empty bitmap node for the next
+ hamt_node_assoc call. */
+ empty = hamt_node_bitmap_new(0);
+ if (empty == NULL) {
+ goto fin;
+ }
+
+ /* Make a new bitmap node for the key/val we're adding.
+ Set that bitmap node to new-array-node[jdx]. */
+ new_node->a_array[jdx] = hamt_node_assoc(
+ empty, shift + 5, hash, key, val, added_leaf);
+ if (new_node->a_array[jdx] == NULL) {
+ goto fin;
+ }
+
+ /* Copy existing key/value pairs from the current Bitmap
+ node to the new Array node we've just created. */
+ Py_ssize_t i, j;
+ for (i = 0, j = 0; i < HAMT_ARRAY_NODE_SIZE; i++) {
+ if (((self->b_bitmap >> i) & 1) != 0) {
+ /* Ensure we don't accidentally override `jdx` element
+ we set few lines above.
+ */
+ assert(new_node->a_array[i] == NULL);
+
+ if (self->b_array[j] == NULL) {
+ new_node->a_array[i] =
+ (PyHamtNode *)self->b_array[j + 1];
+ Py_INCREF(new_node->a_array[i]);
+ }
+ else {
+ int32_t rehash = hamt_hash(self->b_array[j]);
+ if (rehash == -1) {
+ goto fin;
+ }
+
+ new_node->a_array[i] = hamt_node_assoc(
+ empty, shift + 5,
+ rehash,
+ self->b_array[j],
+ self->b_array[j + 1],
+ added_leaf);
+
+ if (new_node->a_array[i] == NULL) {
+ goto fin;
+ }
+ }
+ j += 2;
+ }
+ }
+
+ VALIDATE_ARRAY_NODE(new_node)
+
+ /* That's it! */
+ res = (PyHamtNode *)new_node;
+
+ fin:
+ Py_XDECREF(empty);
+ if (res == NULL) {
+ Py_XDECREF(new_node);
+ }
+ return res;
+ }
+ else {
+ /* We have less than 16 keys at this level; let's just
+ create a new bitmap node out of this node with the
+ new key/val pair added. */
+
+ uint32_t key_idx = 2 * idx;
+ uint32_t val_idx = key_idx + 1;
+ uint32_t i;
+
+ *added_leaf = 1;
+
+ /* Allocate new Bitmap node which can have one more key/val
+ pair in addition to what we have already. */
+ PyHamtNode_Bitmap *new_node =
+ (PyHamtNode_Bitmap *)hamt_node_bitmap_new(2 * (n + 1));
+ if (new_node == NULL) {
+ return NULL;
+ }
+
+ /* Copy all keys/values that will be before the new key/value
+ we are adding. */
+ for (i = 0; i < key_idx; i++) {
+ Py_XINCREF(self->b_array[i]);
+ new_node->b_array[i] = self->b_array[i];
+ }
+
+ /* Set the new key/value to the new Bitmap node. */
+ Py_INCREF(key);
+ new_node->b_array[key_idx] = key;
+ Py_INCREF(val);
+ new_node->b_array[val_idx] = val;
+
+ /* Copy all keys/values that will be after the new key/value
+ we are adding. */
+ assert(Py_SIZE(self) >= 0 && Py_SIZE(self) <= 32);
+ for (i = key_idx; i < (uint32_t)Py_SIZE(self); i++) {
+ Py_XINCREF(self->b_array[i]);
+ new_node->b_array[i + 2] = self->b_array[i];
+ }
+
+ new_node->b_bitmap = self->b_bitmap | bit;
+ return (PyHamtNode *)new_node;
+ }
+ }
+}
+
+static hamt_without_t
+hamt_node_bitmap_without(PyHamtNode_Bitmap *self,
+ uint32_t shift, int32_t hash,
+ PyObject *key,
+ PyHamtNode **new_node)
+{
+ uint32_t bit = hamt_bitpos(hash, shift);
+ if ((self->b_bitmap & bit) == 0) {
+ return W_NOT_FOUND;
+ }
+
+ uint32_t idx = hamt_bitindex(self->b_bitmap, bit);
+
+ uint32_t key_idx = 2 * idx;
+ uint32_t val_idx = key_idx + 1;
+
+ PyObject *key_or_null = self->b_array[key_idx];
+ PyObject *val_or_node = self->b_array[val_idx];
+
+ if (key_or_null == NULL) {
+ /* key == NULL means that 'value' is another tree node. */
+
+ PyHamtNode *sub_node = NULL;
+
+ hamt_without_t res = hamt_node_without(
+ (PyHamtNode *)val_or_node,
+ shift + 5, hash, key, &sub_node);
+
+ switch (res) {
+ case W_EMPTY:
+ /* It's impossible for us to receive a W_EMPTY here:
+
+ - Array nodes are converted to Bitmap nodes when
+ we delete 16th item from them;
+
+ - Collision nodes are converted to Bitmap when
+ there is one item in them;
+
+ - Bitmap node's without() inlines single-item
+ sub-nodes.
+
+ So in no situation we can have a single-item
+ Bitmap child of another Bitmap node.
+ */
+ Py_UNREACHABLE();
+
+ case W_NEWNODE: {
+ assert(sub_node != NULL);
+
+ if (IS_BITMAP_NODE(sub_node)) {
+ PyHamtNode_Bitmap *sub_tree = (PyHamtNode_Bitmap *)sub_node;
+ if (hamt_node_bitmap_count(sub_tree) == 1 &&
+ sub_tree->b_array[0] != NULL)
+ {
+ /* A bitmap node with one key/value pair. Just
+ merge it into this node.
+
+ Note that we don't inline Bitmap nodes that
+ have a NULL key -- those nodes point to another
+ tree level, and we cannot simply move tree levels
+ up or down.
+ */
+
+ PyHamtNode_Bitmap *clone = hamt_node_bitmap_clone(self);
+ if (clone == NULL) {
+ Py_DECREF(sub_node);
+ return W_ERROR;
+ }
+
+ PyObject *key = sub_tree->b_array[0];
+ PyObject *val = sub_tree->b_array[1];
+
+ Py_INCREF(key);
+ Py_XSETREF(clone->b_array[key_idx], key);
+ Py_INCREF(val);
+ Py_SETREF(clone->b_array[val_idx], val);
+
+ Py_DECREF(sub_tree);
+
+ *new_node = (PyHamtNode *)clone;
+ return W_NEWNODE;
+ }
+ }
+
+#ifdef Py_DEBUG
+ /* Ensure that Collision.without implementation
+ converts to Bitmap nodes itself.
+ */
+ if (IS_COLLISION_NODE(sub_node)) {
+ assert(hamt_node_collision_count(
+ (PyHamtNode_Collision*)sub_node) > 1);
+ }
+#endif
+
+ PyHamtNode_Bitmap *clone = hamt_node_bitmap_clone(self);
+ if (clone == NULL) {
+ return W_ERROR;
+ }
+
+ Py_SETREF(clone->b_array[val_idx],
+ (PyObject *)sub_node); /* borrow */
+
+ *new_node = (PyHamtNode *)clone;
+ return W_NEWNODE;
+ }
+
+ case W_ERROR:
+ case W_NOT_FOUND:
+ assert(sub_node == NULL);
+ return res;
+
+ default:
+ Py_UNREACHABLE();
+ }
+ }
+ else {
+ /* We have a regular key/value pair */
+
+ int cmp = PyObject_RichCompareBool(key_or_null, key, Py_EQ);
+ if (cmp < 0) {
+ return W_ERROR;
+ }
+ if (cmp == 0) {
+ return W_NOT_FOUND;
+ }
+
+ if (hamt_node_bitmap_count(self) == 1) {
+ return W_EMPTY;
+ }
+
+ *new_node = (PyHamtNode *)
+ hamt_node_bitmap_clone_without(self, bit);
+ if (*new_node == NULL) {
+ return W_ERROR;
+ }
+
+ return W_NEWNODE;
+ }
+}
+
+static hamt_find_t
+hamt_node_bitmap_find(PyHamtNode_Bitmap *self,
+ uint32_t shift, int32_t hash,
+ PyObject *key, PyObject **val)
+{
+ /* Lookup a key in a Bitmap node. */
+
+ uint32_t bit = hamt_bitpos(hash, shift);
+ uint32_t idx;
+ uint32_t key_idx;
+ uint32_t val_idx;
+ PyObject *key_or_null;
+ PyObject *val_or_node;
+ int comp_err;
+
+ if ((self->b_bitmap & bit) == 0) {
+ return F_NOT_FOUND;
+ }
+
+ idx = hamt_bitindex(self->b_bitmap, bit);
+ key_idx = idx * 2;
+ val_idx = key_idx + 1;
+
+ assert(val_idx < (size_t)Py_SIZE(self));
+
+ key_or_null = self->b_array[key_idx];
+ val_or_node = self->b_array[val_idx];
+
+ if (key_or_null == NULL) {
+ /* There are a few keys that have the same hash at the current shift
+ that match our key. Dispatch the lookup further down the tree. */
+ assert(val_or_node != NULL);
+ return hamt_node_find((PyHamtNode *)val_or_node,
+ shift + 5, hash, key, val);
+ }
+
+ /* We have only one key -- a potential match. Let's compare if the
+ key we are looking at is equal to the key we are looking for. */
+ assert(key != NULL);
+ comp_err = PyObject_RichCompareBool(key, key_or_null, Py_EQ);
+ if (comp_err < 0) { /* exception in __eq__ */
+ return F_ERROR;
+ }
+ if (comp_err == 1) { /* key == key_or_null */
+ *val = val_or_node;
+ return F_FOUND;
+ }
+
+ return F_NOT_FOUND;
+}
+
+static int
+hamt_node_bitmap_traverse(PyHamtNode_Bitmap *self, visitproc visit, void *arg)
+{
+ /* Bitmap's tp_traverse */
+
+ Py_ssize_t i;
+
+ for (i = Py_SIZE(self); --i >= 0; ) {
+ Py_VISIT(self->b_array[i]);
+ }
+
+ return 0;
+}
+
+static void
+hamt_node_bitmap_dealloc(PyHamtNode_Bitmap *self)
+{
+ /* Bitmap's tp_dealloc */
+
+ Py_ssize_t len = Py_SIZE(self);
+ Py_ssize_t i;
+
+ PyObject_GC_UnTrack(self);
+ Py_TRASHCAN_BEGIN(self, hamt_node_bitmap_dealloc)
+
+ if (len > 0) {
+ i = len;
+ while (--i >= 0) {
+ Py_XDECREF(self->b_array[i]);
+ }
+ }
+
+ Py_TYPE(self)->tp_free((PyObject *)self);
+ Py_TRASHCAN_END
+}
+
+#ifdef Py_DEBUG
+static int
+hamt_node_bitmap_dump(PyHamtNode_Bitmap *node,
+ _PyUnicodeWriter *writer, int level)
+{
+ /* Debug build: __dump__() method implementation for Bitmap nodes. */
+
+ Py_ssize_t i;
+ PyObject *tmp1;
+ PyObject *tmp2;
+
+ if (_hamt_dump_ident(writer, level + 1)) {
+ goto error;
+ }
+
+ if (_hamt_dump_format(writer, "BitmapNode(size=%zd count=%zd ",
+ Py_SIZE(node), Py_SIZE(node) / 2))
+ {
+ goto error;
+ }
+
+ tmp1 = PyLong_FromUnsignedLong(node->b_bitmap);
+ if (tmp1 == NULL) {
+ goto error;
+ }
+ tmp2 = _PyLong_Format(tmp1, 2);
+ Py_DECREF(tmp1);
+ if (tmp2 == NULL) {
+ goto error;
+ }
+ if (_hamt_dump_format(writer, "bitmap=%S id=%p):\n", tmp2, node)) {
+ Py_DECREF(tmp2);
+ goto error;
+ }
+ Py_DECREF(tmp2);
+
+ for (i = 0; i < Py_SIZE(node); i += 2) {
+ PyObject *key_or_null = node->b_array[i];
+ PyObject *val_or_node = node->b_array[i + 1];
+
+ if (_hamt_dump_ident(writer, level + 2)) {
+ goto error;
+ }
+
+ if (key_or_null == NULL) {
+ if (_hamt_dump_format(writer, "NULL:\n")) {
+ goto error;
+ }
+
+ if (hamt_node_dump((PyHamtNode *)val_or_node,
+ writer, level + 2))
+ {
+ goto error;
+ }
+ }
+ else {
+ if (_hamt_dump_format(writer, "%R: %R", key_or_null,
+ val_or_node))
+ {
+ goto error;
+ }
+ }
+
+ if (_hamt_dump_format(writer, "\n")) {
+ goto error;
+ }
+ }
+
+ return 0;
+error:
+ return -1;
+}
+#endif /* Py_DEBUG */
+
+
+/////////////////////////////////// Collision Node
+
+
+static PyHamtNode *
+hamt_node_collision_new(int32_t hash, Py_ssize_t size)
+{
+ /* Create a new Collision node. */
+
+ PyHamtNode_Collision *node;
+ Py_ssize_t i;
+
+ assert(size >= 4);
+ assert(size % 2 == 0);
+
+ node = PyObject_GC_NewVar(
+ PyHamtNode_Collision, &_PyHamt_CollisionNode_Type, size);
+ if (node == NULL) {
+ return NULL;
+ }
+
+ for (i = 0; i < size; i++) {
+ node->c_array[i] = NULL;
+ }
+
+ Py_SET_SIZE(node, size);
+ node->c_hash = hash;
+
+ _PyObject_GC_TRACK(node);
+
+ return (PyHamtNode *)node;
+}
+
+static hamt_find_t
+hamt_node_collision_find_index(PyHamtNode_Collision *self, PyObject *key,
+ Py_ssize_t *idx)
+{
+ /* Lookup `key` in the Collision node `self`. Set the index of the
+ found key to 'idx'. */
+
+ Py_ssize_t i;
+ PyObject *el;
+
+ for (i = 0; i < Py_SIZE(self); i += 2) {
+ el = self->c_array[i];
+
+ assert(el != NULL);
+ int cmp = PyObject_RichCompareBool(key, el, Py_EQ);
+ if (cmp < 0) {
+ return F_ERROR;
+ }
+ if (cmp == 1) {
+ *idx = i;
+ return F_FOUND;
+ }
+ }
+
+ return F_NOT_FOUND;
+}
+
+static PyHamtNode *
+hamt_node_collision_assoc(PyHamtNode_Collision *self,
+ uint32_t shift, int32_t hash,
+ PyObject *key, PyObject *val, int* added_leaf)
+{
+ /* Set a new key to this level (currently a Collision node)
+ of the tree. */
+
+ if (hash == self->c_hash) {
+ /* The hash of the 'key' we are adding matches the hash of
+ other keys in this Collision node. */
+
+ Py_ssize_t key_idx = -1;
+ hamt_find_t found;
+ PyHamtNode_Collision *new_node;
+ Py_ssize_t i;
+
+ /* Let's try to lookup the new 'key', maybe we already have it. */
+ found = hamt_node_collision_find_index(self, key, &key_idx);
+ switch (found) {
+ case F_ERROR:
+ /* Exception. */
+ return NULL;
+
+ case F_NOT_FOUND:
+ /* This is a totally new key. Clone the current node,
+ add a new key/value to the cloned node. */
+
+ new_node = (PyHamtNode_Collision *)hamt_node_collision_new(
+ self->c_hash, Py_SIZE(self) + 2);
+ if (new_node == NULL) {
+ return NULL;
+ }
+
+ for (i = 0; i < Py_SIZE(self); i++) {
+ Py_INCREF(self->c_array[i]);
+ new_node->c_array[i] = self->c_array[i];
+ }
+
+ Py_INCREF(key);
+ new_node->c_array[i] = key;
+ Py_INCREF(val);
+ new_node->c_array[i + 1] = val;
+
+ *added_leaf = 1;
+ return (PyHamtNode *)new_node;
+
+ case F_FOUND:
+ /* There's a key which is equal to the key we are adding. */
+
+ assert(key_idx >= 0);
+ assert(key_idx < Py_SIZE(self));
+ Py_ssize_t val_idx = key_idx + 1;
+
+ if (self->c_array[val_idx] == val) {
+ /* We're setting a key/value pair that's already set. */
+ Py_INCREF(self);
+ return (PyHamtNode *)self;
+ }
+
+ /* We need to replace old value for the key
+ with a new value. Create a new Collision node.*/
+ new_node = (PyHamtNode_Collision *)hamt_node_collision_new(
+ self->c_hash, Py_SIZE(self));
+ if (new_node == NULL) {
+ return NULL;
+ }
+
+ /* Copy all elements of the old node to the new one. */
+ for (i = 0; i < Py_SIZE(self); i++) {
+ Py_INCREF(self->c_array[i]);
+ new_node->c_array[i] = self->c_array[i];
+ }
+
+ /* Replace the old value with the new value for the our key. */
+ Py_DECREF(new_node->c_array[val_idx]);
+ Py_INCREF(val);
+ new_node->c_array[val_idx] = val;
+
+ return (PyHamtNode *)new_node;
+
+ default:
+ Py_UNREACHABLE();
+ }
+ }
+ else {
+ /* The hash of the new key is different from the hash that
+ all keys of this Collision node have.
+
+ Create a Bitmap node inplace with two children:
+ key/value pair that we're adding, and the Collision node
+ we're replacing on this tree level.
+ */
+
+ PyHamtNode_Bitmap *new_node;
+ PyHamtNode *assoc_res;
+
+ new_node = (PyHamtNode_Bitmap *)hamt_node_bitmap_new(2);
+ if (new_node == NULL) {
+ return NULL;
+ }
+ new_node->b_bitmap = hamt_bitpos(self->c_hash, shift);
+ Py_INCREF(self);
+ new_node->b_array[1] = (PyObject*) self;
+
+ assoc_res = hamt_node_bitmap_assoc(
+ new_node, shift, hash, key, val, added_leaf);
+ Py_DECREF(new_node);
+ return assoc_res;
+ }
+}
+
+static inline Py_ssize_t
+hamt_node_collision_count(PyHamtNode_Collision *node)
+{
+ return Py_SIZE(node) / 2;
+}
+
+static hamt_without_t
+hamt_node_collision_without(PyHamtNode_Collision *self,
+ uint32_t shift, int32_t hash,
+ PyObject *key,
+ PyHamtNode **new_node)
+{
+ if (hash != self->c_hash) {
+ return W_NOT_FOUND;
+ }
+
+ Py_ssize_t key_idx = -1;
+ hamt_find_t found = hamt_node_collision_find_index(self, key, &key_idx);
+
+ switch (found) {
+ case F_ERROR:
+ return W_ERROR;
+
+ case F_NOT_FOUND:
+ return W_NOT_FOUND;
+
+ case F_FOUND:
+ assert(key_idx >= 0);
+ assert(key_idx < Py_SIZE(self));
+
+ Py_ssize_t new_count = hamt_node_collision_count(self) - 1;
+
+ if (new_count == 0) {
+ /* The node has only one key/value pair and it's for the
+ key we're trying to delete. So a new node will be empty
+ after the removal.
+ */
+ return W_EMPTY;
+ }
+
+ if (new_count == 1) {
+ /* The node has two keys, and after deletion the
+ new Collision node would have one. Collision nodes
+ with one key shouldn't exist, so convert it to a
+ Bitmap node.
+ */
+ PyHamtNode_Bitmap *node = (PyHamtNode_Bitmap *)
+ hamt_node_bitmap_new(2);
+ if (node == NULL) {
+ return W_ERROR;
+ }
+
+ if (key_idx == 0) {
+ Py_INCREF(self->c_array[2]);
+ node->b_array[0] = self->c_array[2];
+ Py_INCREF(self->c_array[3]);
+ node->b_array[1] = self->c_array[3];
+ }
+ else {
+ assert(key_idx == 2);
+ Py_INCREF(self->c_array[0]);
+ node->b_array[0] = self->c_array[0];
+ Py_INCREF(self->c_array[1]);
+ node->b_array[1] = self->c_array[1];
+ }
+
+ node->b_bitmap = hamt_bitpos(hash, shift);
+
+ *new_node = (PyHamtNode *)node;
+ return W_NEWNODE;
+ }
+
+ /* Allocate a new Collision node with capacity for one
+ less key/value pair */
+ PyHamtNode_Collision *new = (PyHamtNode_Collision *)
+ hamt_node_collision_new(
+ self->c_hash, Py_SIZE(self) - 2);
+ if (new == NULL) {
+ return W_ERROR;
+ }
+
+ /* Copy all other keys from `self` to `new` */
+ Py_ssize_t i;
+ for (i = 0; i < key_idx; i++) {
+ Py_INCREF(self->c_array[i]);
+ new->c_array[i] = self->c_array[i];
+ }
+ for (i = key_idx + 2; i < Py_SIZE(self); i++) {
+ Py_INCREF(self->c_array[i]);
+ new->c_array[i - 2] = self->c_array[i];
+ }
+
+ *new_node = (PyHamtNode*)new;
+ return W_NEWNODE;
+
+ default:
+ Py_UNREACHABLE();
+ }
+}
+
+static hamt_find_t
+hamt_node_collision_find(PyHamtNode_Collision *self,
+ uint32_t shift, int32_t hash,
+ PyObject *key, PyObject **val)
+{
+ /* Lookup `key` in the Collision node `self`. Set the value
+ for the found key to 'val'. */
+
+ Py_ssize_t idx = -1;
+ hamt_find_t res;
+
+ res = hamt_node_collision_find_index(self, key, &idx);
+ if (res == F_ERROR || res == F_NOT_FOUND) {
+ return res;
+ }
+
+ assert(idx >= 0);
+ assert(idx + 1 < Py_SIZE(self));
+
+ *val = self->c_array[idx + 1];
+ assert(*val != NULL);
+
+ return F_FOUND;
+}
+
+
+static int
+hamt_node_collision_traverse(PyHamtNode_Collision *self,
+ visitproc visit, void *arg)
+{
+ /* Collision's tp_traverse */
+
+ Py_ssize_t i;
+
+ for (i = Py_SIZE(self); --i >= 0; ) {
+ Py_VISIT(self->c_array[i]);
+ }
+
+ return 0;
+}
+
+static void
+hamt_node_collision_dealloc(PyHamtNode_Collision *self)
+{
+ /* Collision's tp_dealloc */
+
+ Py_ssize_t len = Py_SIZE(self);
+
+ PyObject_GC_UnTrack(self);
+ Py_TRASHCAN_BEGIN(self, hamt_node_collision_dealloc)
+
+ if (len > 0) {
+
+ while (--len >= 0) {
+ Py_XDECREF(self->c_array[len]);
+ }
+ }
+
+ Py_TYPE(self)->tp_free((PyObject *)self);
+ Py_TRASHCAN_END
+}
+
+#ifdef Py_DEBUG
+static int
+hamt_node_collision_dump(PyHamtNode_Collision *node,
+ _PyUnicodeWriter *writer, int level)
+{
+ /* Debug build: __dump__() method implementation for Collision nodes. */
+
+ Py_ssize_t i;
+
+ if (_hamt_dump_ident(writer, level + 1)) {
+ goto error;
+ }
+
+ if (_hamt_dump_format(writer, "CollisionNode(size=%zd id=%p):\n",
+ Py_SIZE(node), node))
+ {
+ goto error;
+ }
+
+ for (i = 0; i < Py_SIZE(node); i += 2) {
+ PyObject *key = node->c_array[i];
+ PyObject *val = node->c_array[i + 1];
+
+ if (_hamt_dump_ident(writer, level + 2)) {
+ goto error;
+ }
+
+ if (_hamt_dump_format(writer, "%R: %R\n", key, val)) {
+ goto error;
+ }
+ }
+
+ return 0;
+error:
+ return -1;
+}
+#endif /* Py_DEBUG */
+
+
+/////////////////////////////////// Array Node
+
+
+static PyHamtNode *
+hamt_node_array_new(Py_ssize_t count)
+{
+ Py_ssize_t i;
+
+ PyHamtNode_Array *node = PyObject_GC_New(
+ PyHamtNode_Array, &_PyHamt_ArrayNode_Type);
+ if (node == NULL) {
+ return NULL;
+ }
+
+ for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) {
+ node->a_array[i] = NULL;
+ }
+
+ node->a_count = count;
+
+ _PyObject_GC_TRACK(node);
+ return (PyHamtNode *)node;
+}
+
+static PyHamtNode_Array *
+hamt_node_array_clone(PyHamtNode_Array *node)
+{
+ PyHamtNode_Array *clone;
+ Py_ssize_t i;
+
+ VALIDATE_ARRAY_NODE(node)
+
+ /* Create a new Array node. */
+ clone = (PyHamtNode_Array *)hamt_node_array_new(node->a_count);
+ if (clone == NULL) {
+ return NULL;
+ }
+
+ /* Copy all elements from the current Array node to the new one. */
+ for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) {
+ Py_XINCREF(node->a_array[i]);
+ clone->a_array[i] = node->a_array[i];
+ }
+
+ VALIDATE_ARRAY_NODE(clone)
+ return clone;
+}
+
+static PyHamtNode *
+hamt_node_array_assoc(PyHamtNode_Array *self,
+ uint32_t shift, int32_t hash,
+ PyObject *key, PyObject *val, int* added_leaf)
+{
+ /* Set a new key to this level (currently a Collision node)
+ of the tree.
+
+ Array nodes don't store values, they can only point to
+ other nodes. They are simple arrays of 32 BaseNode pointers/
+ */
+
+ uint32_t idx = hamt_mask(hash, shift);
+ PyHamtNode *node = self->a_array[idx];
+ PyHamtNode *child_node;
+ PyHamtNode_Array *new_node;
+ Py_ssize_t i;
+
+ if (node == NULL) {
+ /* There's no child node for the given hash. Create a new
+ Bitmap node for this key. */
+
+ PyHamtNode_Bitmap *empty = NULL;
+
+ /* Get an empty Bitmap node to work with. */
+ empty = (PyHamtNode_Bitmap *)hamt_node_bitmap_new(0);
+ if (empty == NULL) {
+ return NULL;
+ }
+
+ /* Set key/val to the newly created empty Bitmap, thus
+ creating a new Bitmap node with our key/value pair. */
+ child_node = hamt_node_bitmap_assoc(
+ empty,
+ shift + 5, hash, key, val, added_leaf);
+ Py_DECREF(empty);
+ if (child_node == NULL) {
+ return NULL;
+ }
+
+ /* Create a new Array node. */
+ new_node = (PyHamtNode_Array *)hamt_node_array_new(self->a_count + 1);
+ if (new_node == NULL) {
+ Py_DECREF(child_node);
+ return NULL;
+ }
+
+ /* Copy all elements from the current Array node to the
+ new one. */
+ for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) {
+ Py_XINCREF(self->a_array[i]);
+ new_node->a_array[i] = self->a_array[i];
+ }
+
+ assert(new_node->a_array[idx] == NULL);
+ new_node->a_array[idx] = child_node; /* borrow */
+ VALIDATE_ARRAY_NODE(new_node)
+ }
+ else {
+ /* There's a child node for the given hash.
+ Set the key to it./ */
+ child_node = hamt_node_assoc(
+ node, shift + 5, hash, key, val, added_leaf);
+ if (child_node == NULL) {
+ return NULL;
+ }
+ else if (child_node == (PyHamtNode *)self) {
+ Py_DECREF(child_node);
+ return (PyHamtNode *)self;
+ }
+
+ new_node = hamt_node_array_clone(self);
+ if (new_node == NULL) {
+ Py_DECREF(child_node);
+ return NULL;
+ }
+
+ Py_SETREF(new_node->a_array[idx], child_node); /* borrow */
+ VALIDATE_ARRAY_NODE(new_node)
+ }
+
+ return (PyHamtNode *)new_node;
+}
+
+static hamt_without_t
+hamt_node_array_without(PyHamtNode_Array *self,
+ uint32_t shift, int32_t hash,
+ PyObject *key,
+ PyHamtNode **new_node)
+{
+ uint32_t idx = hamt_mask(hash, shift);
+ PyHamtNode *node = self->a_array[idx];
+
+ if (node == NULL) {
+ return W_NOT_FOUND;
+ }
+
+ PyHamtNode *sub_node = NULL;
+ hamt_without_t res = hamt_node_without(
+ (PyHamtNode *)node,
+ shift + 5, hash, key, &sub_node);
+
+ switch (res) {
+ case W_NOT_FOUND:
+ case W_ERROR:
+ assert(sub_node == NULL);
+ return res;
+
+ case W_NEWNODE: {
+ /* We need to replace a node at the `idx` index.
+ Clone this node and replace.
+ */
+ assert(sub_node != NULL);
+
+ PyHamtNode_Array *clone = hamt_node_array_clone(self);
+ if (clone == NULL) {
+ Py_DECREF(sub_node);
+ return W_ERROR;
+ }
+
+ Py_SETREF(clone->a_array[idx], sub_node); /* borrow */
+ *new_node = (PyHamtNode*)clone; /* borrow */
+ return W_NEWNODE;
+ }
+
+ case W_EMPTY: {
+ assert(sub_node == NULL);
+ /* We need to remove a node at the `idx` index.
+ Calculate the size of the replacement Array node.
+ */
+ Py_ssize_t new_count = self->a_count - 1;
+
+ if (new_count == 0) {
+ return W_EMPTY;
+ }
+
+ if (new_count >= 16) {
+ /* We convert Bitmap nodes to Array nodes, when a
+ Bitmap node needs to store more than 15 key/value
+ pairs. So we will create a new Array node if we
+ the number of key/values after deletion is still
+ greater than 15.
+ */
+
+ PyHamtNode_Array *new = hamt_node_array_clone(self);
+ if (new == NULL) {
+ return W_ERROR;
+ }
+ new->a_count = new_count;
+ Py_CLEAR(new->a_array[idx]);
+
+ *new_node = (PyHamtNode*)new; /* borrow */
+ return W_NEWNODE;
+ }
+
+ /* New Array node would have less than 16 key/value
+ pairs. We need to create a replacement Bitmap node. */
+
+ Py_ssize_t bitmap_size = new_count * 2;
+ uint32_t bitmap = 0;
+
+ PyHamtNode_Bitmap *new = (PyHamtNode_Bitmap *)
+ hamt_node_bitmap_new(bitmap_size);
+ if (new == NULL) {
+ return W_ERROR;
+ }
+
+ Py_ssize_t new_i = 0;
+ for (uint32_t i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) {
+ if (i == idx) {
+ /* Skip the node we are deleting. */
+ continue;
+ }
+
+ PyHamtNode *node = self->a_array[i];
+ if (node == NULL) {
+ /* Skip any missing nodes. */
+ continue;
+ }
+
+ bitmap |= 1U << i;
+
+ if (IS_BITMAP_NODE(node)) {
+ PyHamtNode_Bitmap *child = (PyHamtNode_Bitmap *)node;
+
+ if (hamt_node_bitmap_count(child) == 1 &&
+ child->b_array[0] != NULL)
+ {
+ /* node is a Bitmap with one key/value pair, just
+ merge it into the new Bitmap node we're building.
+
+ Note that we don't inline Bitmap nodes that
+ have a NULL key -- those nodes point to another
+ tree level, and we cannot simply move tree levels
+ up or down.
+ */
+ PyObject *key = child->b_array[0];
+ PyObject *val = child->b_array[1];
+
+ Py_INCREF(key);
+ new->b_array[new_i] = key;
+ Py_INCREF(val);
+ new->b_array[new_i + 1] = val;
+ }
+ else {
+ new->b_array[new_i] = NULL;
+ Py_INCREF(node);
+ new->b_array[new_i + 1] = (PyObject*)node;
+ }
+ }
+ else {
+
+#ifdef Py_DEBUG
+ if (IS_COLLISION_NODE(node)) {
+ Py_ssize_t child_count = hamt_node_collision_count(
+ (PyHamtNode_Collision*)node);
+ assert(child_count > 1);
+ }
+ else if (IS_ARRAY_NODE(node)) {
+ assert(((PyHamtNode_Array*)node)->a_count >= 16);
+ }
+#endif
+
+ /* Just copy the node into our new Bitmap */
+ new->b_array[new_i] = NULL;
+ Py_INCREF(node);
+ new->b_array[new_i + 1] = (PyObject*)node;
+ }
+
+ new_i += 2;
+ }
+
+ new->b_bitmap = bitmap;
+ *new_node = (PyHamtNode*)new; /* borrow */
+ return W_NEWNODE;
+ }
+
+ default:
+ Py_UNREACHABLE();
+ }
+}
+
+static hamt_find_t
+hamt_node_array_find(PyHamtNode_Array *self,
+ uint32_t shift, int32_t hash,
+ PyObject *key, PyObject **val)
+{
+ /* Lookup `key` in the Array node `self`. Set the value
+ for the found key to 'val'. */
+
+ uint32_t idx = hamt_mask(hash, shift);
+ PyHamtNode *node;
+
+ node = self->a_array[idx];
+ if (node == NULL) {
+ return F_NOT_FOUND;
+ }
+
+ /* Dispatch to the generic hamt_node_find */
+ return hamt_node_find(node, shift + 5, hash, key, val);
+}
+
+static int
+hamt_node_array_traverse(PyHamtNode_Array *self,
+ visitproc visit, void *arg)
+{
+ /* Array's tp_traverse */
+
+ Py_ssize_t i;
+
+ for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) {
+ Py_VISIT(self->a_array[i]);
+ }
+
+ return 0;
+}
+
+static void
+hamt_node_array_dealloc(PyHamtNode_Array *self)
+{
+ /* Array's tp_dealloc */
+
+ Py_ssize_t i;
+
+ PyObject_GC_UnTrack(self);
+ Py_TRASHCAN_BEGIN(self, hamt_node_array_dealloc)
+
+ for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) {
+ Py_XDECREF(self->a_array[i]);
+ }
+
+ Py_TYPE(self)->tp_free((PyObject *)self);
+ Py_TRASHCAN_END
+}
+
+#ifdef Py_DEBUG
+static int
+hamt_node_array_dump(PyHamtNode_Array *node,
+ _PyUnicodeWriter *writer, int level)
+{
+ /* Debug build: __dump__() method implementation for Array nodes. */
+
+ Py_ssize_t i;
+
+ if (_hamt_dump_ident(writer, level + 1)) {
+ goto error;
+ }
+
+ if (_hamt_dump_format(writer, "ArrayNode(id=%p):\n", node)) {
+ goto error;
+ }
+
+ for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) {
+ if (node->a_array[i] == NULL) {
+ continue;
+ }
+
+ if (_hamt_dump_ident(writer, level + 2)) {
+ goto error;
+ }
+
+ if (_hamt_dump_format(writer, "%zd::\n", i)) {
+ goto error;
+ }
+
+ if (hamt_node_dump(node->a_array[i], writer, level + 1)) {
+ goto error;
+ }
+
+ if (_hamt_dump_format(writer, "\n")) {
+ goto error;
+ }
+ }
+
+ return 0;
+error:
+ return -1;
+}
+#endif /* Py_DEBUG */
+
+
+/////////////////////////////////// Node Dispatch
+
+
+static PyHamtNode *
+hamt_node_assoc(PyHamtNode *node,
+ uint32_t shift, int32_t hash,
+ PyObject *key, PyObject *val, int* added_leaf)
+{
+ /* Set key/value to the 'node' starting with the given shift/hash.
+ Return a new node, or the same node if key/value already
+ set.
+
+ added_leaf will be set to 1 if key/value wasn't in the
+ tree before.
+
+ This method automatically dispatches to the suitable
+ hamt_node_{nodetype}_assoc method.
+ */
+
+ if (IS_BITMAP_NODE(node)) {
+ return hamt_node_bitmap_assoc(
+ (PyHamtNode_Bitmap *)node,
+ shift, hash, key, val, added_leaf);
+ }
+ else if (IS_ARRAY_NODE(node)) {
+ return hamt_node_array_assoc(
+ (PyHamtNode_Array *)node,
+ shift, hash, key, val, added_leaf);
+ }
+ else {
+ assert(IS_COLLISION_NODE(node));
+ return hamt_node_collision_assoc(
+ (PyHamtNode_Collision *)node,
+ shift, hash, key, val, added_leaf);
+ }
+}
+
+static hamt_without_t
+hamt_node_without(PyHamtNode *node,
+ uint32_t shift, int32_t hash,
+ PyObject *key,
+ PyHamtNode **new_node)
+{
+ if (IS_BITMAP_NODE(node)) {
+ return hamt_node_bitmap_without(
+ (PyHamtNode_Bitmap *)node,
+ shift, hash, key,
+ new_node);
+ }
+ else if (IS_ARRAY_NODE(node)) {
+ return hamt_node_array_without(
+ (PyHamtNode_Array *)node,
+ shift, hash, key,
+ new_node);
+ }
+ else {
+ assert(IS_COLLISION_NODE(node));
+ return hamt_node_collision_without(
+ (PyHamtNode_Collision *)node,
+ shift, hash, key,
+ new_node);
+ }
+}
+
+static hamt_find_t
+hamt_node_find(PyHamtNode *node,
+ uint32_t shift, int32_t hash,
+ PyObject *key, PyObject **val)
+{
+ /* Find the key in the node starting with the given shift/hash.
+
+ If a value is found, the result will be set to F_FOUND, and
+ *val will point to the found value object.
+
+ If a value wasn't found, the result will be set to F_NOT_FOUND.
+
+ If an exception occurs during the call, the result will be F_ERROR.
+
+ This method automatically dispatches to the suitable
+ hamt_node_{nodetype}_find method.
+ */
+
+ if (IS_BITMAP_NODE(node)) {
+ return hamt_node_bitmap_find(
+ (PyHamtNode_Bitmap *)node,
+ shift, hash, key, val);
+
+ }
+ else if (IS_ARRAY_NODE(node)) {
+ return hamt_node_array_find(
+ (PyHamtNode_Array *)node,
+ shift, hash, key, val);
+ }
+ else {
+ assert(IS_COLLISION_NODE(node));
+ return hamt_node_collision_find(
+ (PyHamtNode_Collision *)node,
+ shift, hash, key, val);
+ }
+}
+
+#ifdef Py_DEBUG
+static int
+hamt_node_dump(PyHamtNode *node,
+ _PyUnicodeWriter *writer, int level)
+{
+ /* Debug build: __dump__() method implementation for a node.
+
+ This method automatically dispatches to the suitable
+ hamt_node_{nodetype})_dump method.
+ */
+
+ if (IS_BITMAP_NODE(node)) {
+ return hamt_node_bitmap_dump(
+ (PyHamtNode_Bitmap *)node, writer, level);
+ }
+ else if (IS_ARRAY_NODE(node)) {
+ return hamt_node_array_dump(
+ (PyHamtNode_Array *)node, writer, level);
+ }
+ else {
+ assert(IS_COLLISION_NODE(node));
+ return hamt_node_collision_dump(
+ (PyHamtNode_Collision *)node, writer, level);
+ }
+}
+#endif /* Py_DEBUG */
+
+
+/////////////////////////////////// Iterators: Machinery
+
+
+static hamt_iter_t
+hamt_iterator_next(PyHamtIteratorState *iter, PyObject **key, PyObject **val);
+
+
+static void
+hamt_iterator_init(PyHamtIteratorState *iter, PyHamtNode *root)
+{
+ for (uint32_t i = 0; i < _Py_HAMT_MAX_TREE_DEPTH; i++) {
+ iter->i_nodes[i] = NULL;
+ iter->i_pos[i] = 0;
+ }
+
+ iter->i_level = 0;
+
+ /* Note: we don't incref/decref nodes in i_nodes. */
+ iter->i_nodes[0] = root;
+}
+
+static hamt_iter_t
+hamt_iterator_bitmap_next(PyHamtIteratorState *iter,
+ PyObject **key, PyObject **val)
+{
+ int8_t level = iter->i_level;
+
+ PyHamtNode_Bitmap *node = (PyHamtNode_Bitmap *)(iter->i_nodes[level]);
+ Py_ssize_t pos = iter->i_pos[level];
+
+ if (pos + 1 >= Py_SIZE(node)) {
+#ifdef Py_DEBUG
+ assert(iter->i_level >= 0);
+ iter->i_nodes[iter->i_level] = NULL;
+#endif
+ iter->i_level--;
+ return hamt_iterator_next(iter, key, val);
+ }
+
+ if (node->b_array[pos] == NULL) {
+ iter->i_pos[level] = pos + 2;
+
+ int8_t next_level = level + 1;
+ assert(next_level < _Py_HAMT_MAX_TREE_DEPTH);
+ iter->i_level = next_level;
+ iter->i_pos[next_level] = 0;
+ iter->i_nodes[next_level] = (PyHamtNode *)
+ node->b_array[pos + 1];
+
+ return hamt_iterator_next(iter, key, val);
+ }
+
+ *key = node->b_array[pos];
+ *val = node->b_array[pos + 1];
+ iter->i_pos[level] = pos + 2;
+ return I_ITEM;
+}
+
+static hamt_iter_t
+hamt_iterator_collision_next(PyHamtIteratorState *iter,
+ PyObject **key, PyObject **val)
+{
+ int8_t level = iter->i_level;
+
+ PyHamtNode_Collision *node = (PyHamtNode_Collision *)(iter->i_nodes[level]);
+ Py_ssize_t pos = iter->i_pos[level];
+
+ if (pos + 1 >= Py_SIZE(node)) {
+#ifdef Py_DEBUG
+ assert(iter->i_level >= 0);
+ iter->i_nodes[iter->i_level] = NULL;
+#endif
+ iter->i_level--;
+ return hamt_iterator_next(iter, key, val);
+ }
+
+ *key = node->c_array[pos];
+ *val = node->c_array[pos + 1];
+ iter->i_pos[level] = pos + 2;
+ return I_ITEM;
+}
+
+static hamt_iter_t
+hamt_iterator_array_next(PyHamtIteratorState *iter,
+ PyObject **key, PyObject **val)
+{
+ int8_t level = iter->i_level;
+
+ PyHamtNode_Array *node = (PyHamtNode_Array *)(iter->i_nodes[level]);
+ Py_ssize_t pos = iter->i_pos[level];
+
+ if (pos >= HAMT_ARRAY_NODE_SIZE) {
+#ifdef Py_DEBUG
+ assert(iter->i_level >= 0);
+ iter->i_nodes[iter->i_level] = NULL;
+#endif
+ iter->i_level--;
+ return hamt_iterator_next(iter, key, val);
+ }
+
+ for (Py_ssize_t i = pos; i < HAMT_ARRAY_NODE_SIZE; i++) {
+ if (node->a_array[i] != NULL) {
+ iter->i_pos[level] = i + 1;
+
+ int8_t next_level = level + 1;
+ assert(next_level < _Py_HAMT_MAX_TREE_DEPTH);
+ iter->i_pos[next_level] = 0;
+ iter->i_nodes[next_level] = node->a_array[i];
+ iter->i_level = next_level;
+
+ return hamt_iterator_next(iter, key, val);
+ }
+ }
+
+#ifdef Py_DEBUG
+ assert(iter->i_level >= 0);
+ iter->i_nodes[iter->i_level] = NULL;
+#endif
+
+ iter->i_level--;
+ return hamt_iterator_next(iter, key, val);
+}
+
+static hamt_iter_t
+hamt_iterator_next(PyHamtIteratorState *iter, PyObject **key, PyObject **val)
+{
+ if (iter->i_level < 0) {
+ return I_END;
+ }
+
+ assert(iter->i_level < _Py_HAMT_MAX_TREE_DEPTH);
+
+ PyHamtNode *current = iter->i_nodes[iter->i_level];
+
+ if (IS_BITMAP_NODE(current)) {
+ return hamt_iterator_bitmap_next(iter, key, val);
+ }
+ else if (IS_ARRAY_NODE(current)) {
+ return hamt_iterator_array_next(iter, key, val);
+ }
+ else {
+ assert(IS_COLLISION_NODE(current));
+ return hamt_iterator_collision_next(iter, key, val);
+ }
+}
+
+
+/////////////////////////////////// HAMT high-level functions
+
+
+PyHamtObject *
+_PyHamt_Assoc(PyHamtObject *o, PyObject *key, PyObject *val)
+{
+ int32_t key_hash;
+ int added_leaf = 0;
+ PyHamtNode *new_root;
+ PyHamtObject *new_o;
+
+ key_hash = hamt_hash(key);
+ if (key_hash == -1) {
+ return NULL;
+ }
+
+ new_root = hamt_node_assoc(
+ (PyHamtNode *)(o->h_root),
+ 0, key_hash, key, val, &added_leaf);
+ if (new_root == NULL) {
+ return NULL;
+ }
+
+ if (new_root == o->h_root) {
+ Py_DECREF(new_root);
+ Py_INCREF(o);
+ return o;
+ }
+
+ new_o = hamt_alloc();
+ if (new_o == NULL) {
+ Py_DECREF(new_root);
+ return NULL;
+ }
+
+ new_o->h_root = new_root; /* borrow */
+ new_o->h_count = added_leaf ? o->h_count + 1 : o->h_count;
+
+ return new_o;
+}
+
+PyHamtObject *
+_PyHamt_Without(PyHamtObject *o, PyObject *key)
+{
+ int32_t key_hash = hamt_hash(key);
+ if (key_hash == -1) {
+ return NULL;
+ }
+
+ PyHamtNode *new_root = NULL;
+
+ hamt_without_t res = hamt_node_without(
+ (PyHamtNode *)(o->h_root),
+ 0, key_hash, key,
+ &new_root);
+
+ switch (res) {
+ case W_ERROR:
+ return NULL;
+ case W_EMPTY:
+ return _PyHamt_New();
+ case W_NOT_FOUND:
+ Py_INCREF(o);
+ return o;
+ case W_NEWNODE: {
+ assert(new_root != NULL);
+
+ PyHamtObject *new_o = hamt_alloc();
+ if (new_o == NULL) {
+ Py_DECREF(new_root);
+ return NULL;
+ }
+
+ new_o->h_root = new_root; /* borrow */
+ new_o->h_count = o->h_count - 1;
+ assert(new_o->h_count >= 0);
+ return new_o;
+ }
+ default:
+ Py_UNREACHABLE();
+ }
+}
+
+static hamt_find_t
+hamt_find(PyHamtObject *o, PyObject *key, PyObject **val)
+{
+ if (o->h_count == 0) {
+ return F_NOT_FOUND;
+ }
+
+ int32_t key_hash = hamt_hash(key);
+ if (key_hash == -1) {
+ return F_ERROR;
+ }
+
+ return hamt_node_find(o->h_root, 0, key_hash, key, val);
+}
+
+
+int
+_PyHamt_Find(PyHamtObject *o, PyObject *key, PyObject **val)
+{
+ hamt_find_t res = hamt_find(o, key, val);
+ switch (res) {
+ case F_ERROR:
+ return -1;
+ case F_NOT_FOUND:
+ return 0;
+ case F_FOUND:
+ return 1;
+ default:
+ Py_UNREACHABLE();
+ }
+}
+
+
+int
+_PyHamt_Eq(PyHamtObject *v, PyHamtObject *w)
+{
+ if (v == w) {
+ return 1;
+ }
+
+ if (v->h_count != w->h_count) {
+ return 0;
+ }
+
+ PyHamtIteratorState iter;
+ hamt_iter_t iter_res;
+ hamt_find_t find_res;
+ PyObject *v_key;
+ PyObject *v_val;
+ PyObject *w_val;
+
+ hamt_iterator_init(&iter, v->h_root);
+
+ do {
+ iter_res = hamt_iterator_next(&iter, &v_key, &v_val);
+ if (iter_res == I_ITEM) {
+ find_res = hamt_find(w, v_key, &w_val);
+ switch (find_res) {
+ case F_ERROR:
+ return -1;
+
+ case F_NOT_FOUND:
+ return 0;
+
+ case F_FOUND: {
+ int cmp = PyObject_RichCompareBool(v_val, w_val, Py_EQ);
+ if (cmp < 0) {
+ return -1;
+ }
+ if (cmp == 0) {
+ return 0;
+ }
+ }
+ }
+ }
+ } while (iter_res != I_END);
+
+ return 1;
+}
+
+Py_ssize_t
+_PyHamt_Len(PyHamtObject *o)
+{
+ return o->h_count;
+}
+
+static PyHamtObject *
+hamt_alloc(void)
+{
+ PyHamtObject *o;
+ o = PyObject_GC_New(PyHamtObject, &_PyHamt_Type);
+ if (o == NULL) {
+ return NULL;
+ }
+ o->h_count = 0;
+ o->h_root = NULL;
+ o->h_weakreflist = NULL;
+ PyObject_GC_Track(o);
+ return o;
+}
+
+PyHamtObject *
+_PyHamt_New(void)
+{
+ if (_empty_hamt != NULL) {
+ /* HAMT is an immutable object so we can easily cache an
+ empty instance. */
+ Py_INCREF(_empty_hamt);
+ return _empty_hamt;
+ }
+
+ PyHamtObject *o = hamt_alloc();
+ if (o == NULL) {
+ return NULL;
+ }
+
+ o->h_root = hamt_node_bitmap_new(0);
+ if (o->h_root == NULL) {
+ Py_DECREF(o);
+ return NULL;
+ }
+
+ o->h_count = 0;
+
+ if (_empty_hamt == NULL) {
+ Py_INCREF(o);
+ _empty_hamt = o;
+ }
+
+ return o;
+}
+
+#ifdef Py_DEBUG
+static PyObject *
+hamt_dump(PyHamtObject *self)
+{
+ _PyUnicodeWriter writer;
+
+ _PyUnicodeWriter_Init(&writer);
+
+ if (_hamt_dump_format(&writer, "HAMT(len=%zd):\n", self->h_count)) {
+ goto error;
+ }
+
+ if (hamt_node_dump(self->h_root, &writer, 0)) {
+ goto error;
+ }
+
+ return _PyUnicodeWriter_Finish(&writer);
+
+error:
+ _PyUnicodeWriter_Dealloc(&writer);
+ return NULL;
+}
+#endif /* Py_DEBUG */
+
+
+/////////////////////////////////// Iterators: Shared Iterator Implementation
+
+
+static int
+hamt_baseiter_tp_clear(PyHamtIterator *it)
+{
+ Py_CLEAR(it->hi_obj);
+ return 0;
+}
+
+static void
+hamt_baseiter_tp_dealloc(PyHamtIterator *it)
+{
+ PyObject_GC_UnTrack(it);
+ (void)hamt_baseiter_tp_clear(it);
+ PyObject_GC_Del(it);
+}
+
+static int
+hamt_baseiter_tp_traverse(PyHamtIterator *it, visitproc visit, void *arg)
+{
+ Py_VISIT(it->hi_obj);
+ return 0;
+}
+
+static PyObject *
+hamt_baseiter_tp_iternext(PyHamtIterator *it)
+{
+ PyObject *key;
+ PyObject *val;
+ hamt_iter_t res = hamt_iterator_next(&it->hi_iter, &key, &val);
+
+ switch (res) {
+ case I_END:
+ PyErr_SetNone(PyExc_StopIteration);
+ return NULL;
+
+ case I_ITEM: {
+ return (*(it->hi_yield))(key, val);
+ }
+
+ default: {
+ Py_UNREACHABLE();
+ }
+ }
+}
+
+static Py_ssize_t
+hamt_baseiter_tp_len(PyHamtIterator *it)
+{
+ return it->hi_obj->h_count;
+}
+
+static PyMappingMethods PyHamtIterator_as_mapping = {
+ (lenfunc)hamt_baseiter_tp_len,
+};
+
+static PyObject *
+hamt_baseiter_new(PyTypeObject *type, binaryfunc yield, PyHamtObject *o)
+{
+ PyHamtIterator *it = PyObject_GC_New(PyHamtIterator, type);
+ if (it == NULL) {
+ return NULL;
+ }
+
+ Py_INCREF(o);
+ it->hi_obj = o;
+ it->hi_yield = yield;
+
+ hamt_iterator_init(&it->hi_iter, o->h_root);
+
+ return (PyObject*)it;
+}
+
+#define ITERATOR_TYPE_SHARED_SLOTS \
+ .tp_basicsize = sizeof(PyHamtIterator), \
+ .tp_itemsize = 0, \
+ .tp_as_mapping = &PyHamtIterator_as_mapping, \
+ .tp_dealloc = (destructor)hamt_baseiter_tp_dealloc, \
+ .tp_getattro = PyObject_GenericGetAttr, \
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, \
+ .tp_traverse = (traverseproc)hamt_baseiter_tp_traverse, \
+ .tp_clear = (inquiry)hamt_baseiter_tp_clear, \
+ .tp_iter = PyObject_SelfIter, \
+ .tp_iternext = (iternextfunc)hamt_baseiter_tp_iternext,
+
+
+/////////////////////////////////// _PyHamtItems_Type
+
+
+PyTypeObject _PyHamtItems_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "items",
+ ITERATOR_TYPE_SHARED_SLOTS
+};
+
+static PyObject *
+hamt_iter_yield_items(PyObject *key, PyObject *val)
+{
+ return PyTuple_Pack(2, key, val);
+}
+
+PyObject *
+_PyHamt_NewIterItems(PyHamtObject *o)
+{
+ return hamt_baseiter_new(
+ &_PyHamtItems_Type, hamt_iter_yield_items, o);
+}
+
+
+/////////////////////////////////// _PyHamtKeys_Type
+
+
+PyTypeObject _PyHamtKeys_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "keys",
+ ITERATOR_TYPE_SHARED_SLOTS
+};
+
+static PyObject *
+hamt_iter_yield_keys(PyObject *key, PyObject *val)
+{
+ Py_INCREF(key);
+ return key;
+}
+
+PyObject *
+_PyHamt_NewIterKeys(PyHamtObject *o)
+{
+ return hamt_baseiter_new(
+ &_PyHamtKeys_Type, hamt_iter_yield_keys, o);
+}
+
+
+/////////////////////////////////// _PyHamtValues_Type
+
+
+PyTypeObject _PyHamtValues_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "values",
+ ITERATOR_TYPE_SHARED_SLOTS
+};
+
+static PyObject *
+hamt_iter_yield_values(PyObject *key, PyObject *val)
+{
+ Py_INCREF(val);
+ return val;
+}
+
+PyObject *
+_PyHamt_NewIterValues(PyHamtObject *o)
+{
+ return hamt_baseiter_new(
+ &_PyHamtValues_Type, hamt_iter_yield_values, o);
+}
+
+
+/////////////////////////////////// _PyHamt_Type
+
+
+#ifdef Py_DEBUG
+static PyObject *
+hamt_dump(PyHamtObject *self);
+#endif
+
+
+static PyObject *
+hamt_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ return (PyObject*)_PyHamt_New();
+}
+
+static int
+hamt_tp_clear(PyHamtObject *self)
+{
+ Py_CLEAR(self->h_root);
+ return 0;
+}
+
+
+static int
+hamt_tp_traverse(PyHamtObject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->h_root);
+ return 0;
+}
+
+static void
+hamt_tp_dealloc(PyHamtObject *self)
+{
+ PyObject_GC_UnTrack(self);
+ if (self->h_weakreflist != NULL) {
+ PyObject_ClearWeakRefs((PyObject*)self);
+ }
+ (void)hamt_tp_clear(self);
+ Py_TYPE(self)->tp_free(self);
+}
+
+
+static PyObject *
+hamt_tp_richcompare(PyObject *v, PyObject *w, int op)
+{
+ if (!PyHamt_Check(v) || !PyHamt_Check(w) || (op != Py_EQ && op != Py_NE)) {
+ Py_RETURN_NOTIMPLEMENTED;
+ }
+
+ int res = _PyHamt_Eq((PyHamtObject *)v, (PyHamtObject *)w);
+ if (res < 0) {
+ return NULL;
+ }
+
+ if (op == Py_NE) {
+ res = !res;
+ }
+
+ if (res) {
+ Py_RETURN_TRUE;
+ }
+ else {
+ Py_RETURN_FALSE;
+ }
+}
+
+static int
+hamt_tp_contains(PyHamtObject *self, PyObject *key)
+{
+ PyObject *val;
+ return _PyHamt_Find(self, key, &val);
+}
+
+static PyObject *
+hamt_tp_subscript(PyHamtObject *self, PyObject *key)
+{
+ PyObject *val;
+ hamt_find_t res = hamt_find(self, key, &val);
+ switch (res) {
+ case F_ERROR:
+ return NULL;
+ case F_FOUND:
+ Py_INCREF(val);
+ return val;
+ case F_NOT_FOUND:
+ PyErr_SetObject(PyExc_KeyError, key);
+ return NULL;
+ default:
+ Py_UNREACHABLE();
+ }
+}
+
+static Py_ssize_t
+hamt_tp_len(PyHamtObject *self)
+{
+ return _PyHamt_Len(self);
+}
+
+static PyObject *
+hamt_tp_iter(PyHamtObject *self)
+{
+ return _PyHamt_NewIterKeys(self);
+}
+
+static PyObject *
+hamt_py_set(PyHamtObject *self, PyObject *args)
+{
+ PyObject *key;
+ PyObject *val;
+
+ if (!PyArg_UnpackTuple(args, "set", 2, 2, &key, &val)) {
+ return NULL;
+ }
+
+ return (PyObject *)_PyHamt_Assoc(self, key, val);
+}
+
+static PyObject *
+hamt_py_get(PyHamtObject *self, PyObject *args)
+{
+ PyObject *key;
+ PyObject *def = NULL;
+
+ if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &def)) {
+ return NULL;
+ }
+
+ PyObject *val = NULL;
+ hamt_find_t res = hamt_find(self, key, &val);
+ switch (res) {
+ case F_ERROR:
+ return NULL;
+ case F_FOUND:
+ Py_INCREF(val);
+ return val;
+ case F_NOT_FOUND:
+ if (def == NULL) {
+ Py_RETURN_NONE;
+ }
+ Py_INCREF(def);
+ return def;
+ default:
+ Py_UNREACHABLE();
+ }
+}
+
+static PyObject *
+hamt_py_delete(PyHamtObject *self, PyObject *key)
+{
+ return (PyObject *)_PyHamt_Without(self, key);
+}
+
+static PyObject *
+hamt_py_items(PyHamtObject *self, PyObject *args)
+{
+ return _PyHamt_NewIterItems(self);
+}
+
+static PyObject *
+hamt_py_values(PyHamtObject *self, PyObject *args)
+{
+ return _PyHamt_NewIterValues(self);
+}
+
+static PyObject *
+hamt_py_keys(PyHamtObject *self, PyObject *args)
+{
+ return _PyHamt_NewIterKeys(self);
+}
+
+#ifdef Py_DEBUG
+static PyObject *
+hamt_py_dump(PyHamtObject *self, PyObject *args)
+{
+ return hamt_dump(self);
+}
+#endif
+
+
+static PyMethodDef PyHamt_methods[] = {
+ {"set", (PyCFunction)hamt_py_set, METH_VARARGS, NULL},
+ {"get", (PyCFunction)hamt_py_get, METH_VARARGS, NULL},
+ {"delete", (PyCFunction)hamt_py_delete, METH_O, NULL},
+ {"items", (PyCFunction)hamt_py_items, METH_NOARGS, NULL},
+ {"keys", (PyCFunction)hamt_py_keys, METH_NOARGS, NULL},
+ {"values", (PyCFunction)hamt_py_values, METH_NOARGS, NULL},
+#ifdef Py_DEBUG
+ {"__dump__", (PyCFunction)hamt_py_dump, METH_NOARGS, NULL},
+#endif
+ {NULL, NULL}
+};
+
+static PySequenceMethods PyHamt_as_sequence = {
+ 0, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ 0, /* sq_item */
+ 0, /* sq_slice */
+ 0, /* sq_ass_item */
+ 0, /* sq_ass_slice */
+ (objobjproc)hamt_tp_contains, /* sq_contains */
+ 0, /* sq_inplace_concat */
+ 0, /* sq_inplace_repeat */
+};
+
+static PyMappingMethods PyHamt_as_mapping = {
+ (lenfunc)hamt_tp_len, /* mp_length */
+ (binaryfunc)hamt_tp_subscript, /* mp_subscript */
+};
+
+PyTypeObject _PyHamt_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "hamt",
+ sizeof(PyHamtObject),
+ .tp_methods = PyHamt_methods,
+ .tp_as_mapping = &PyHamt_as_mapping,
+ .tp_as_sequence = &PyHamt_as_sequence,
+ .tp_iter = (getiterfunc)hamt_tp_iter,
+ .tp_dealloc = (destructor)hamt_tp_dealloc,
+ .tp_getattro = PyObject_GenericGetAttr,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+ .tp_richcompare = hamt_tp_richcompare,
+ .tp_traverse = (traverseproc)hamt_tp_traverse,
+ .tp_clear = (inquiry)hamt_tp_clear,
+ .tp_new = hamt_tp_new,
+ .tp_weaklistoffset = offsetof(PyHamtObject, h_weakreflist),
+ .tp_hash = PyObject_HashNotImplemented,
+};
+
+
+/////////////////////////////////// Tree Node Types
+
+
+PyTypeObject _PyHamt_ArrayNode_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "hamt_array_node",
+ sizeof(PyHamtNode_Array),
+ 0,
+ .tp_dealloc = (destructor)hamt_node_array_dealloc,
+ .tp_getattro = PyObject_GenericGetAttr,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+ .tp_traverse = (traverseproc)hamt_node_array_traverse,
+ .tp_free = PyObject_GC_Del,
+ .tp_hash = PyObject_HashNotImplemented,
+};
+
+PyTypeObject _PyHamt_BitmapNode_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "hamt_bitmap_node",
+ sizeof(PyHamtNode_Bitmap) - sizeof(PyObject *),
+ sizeof(PyObject *),
+ .tp_dealloc = (destructor)hamt_node_bitmap_dealloc,
+ .tp_getattro = PyObject_GenericGetAttr,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+ .tp_traverse = (traverseproc)hamt_node_bitmap_traverse,
+ .tp_free = PyObject_GC_Del,
+ .tp_hash = PyObject_HashNotImplemented,
+};
+
+PyTypeObject _PyHamt_CollisionNode_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "hamt_collision_node",
+ sizeof(PyHamtNode_Collision) - sizeof(PyObject *),
+ sizeof(PyObject *),
+ .tp_dealloc = (destructor)hamt_node_collision_dealloc,
+ .tp_getattro = PyObject_GenericGetAttr,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+ .tp_traverse = (traverseproc)hamt_node_collision_traverse,
+ .tp_free = PyObject_GC_Del,
+ .tp_hash = PyObject_HashNotImplemented,
+};
+
+
+int
+_PyHamt_Init(void)
+{
+ if ((PyType_Ready(&_PyHamt_Type) < 0) ||
+ (PyType_Ready(&_PyHamt_ArrayNode_Type) < 0) ||
+ (PyType_Ready(&_PyHamt_BitmapNode_Type) < 0) ||
+ (PyType_Ready(&_PyHamt_CollisionNode_Type) < 0) ||
+ (PyType_Ready(&_PyHamtKeys_Type) < 0) ||
+ (PyType_Ready(&_PyHamtValues_Type) < 0) ||
+ (PyType_Ready(&_PyHamtItems_Type) < 0))
+ {
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+_PyHamt_Fini(void)
+{
+ Py_CLEAR(_empty_hamt);
+ Py_CLEAR(_empty_bitmap_node);
+}
diff --git a/contrib/tools/python3/src/Python/hashtable.c b/contrib/tools/python3/src/Python/hashtable.c
new file mode 100644
index 00000000000..09501de199b
--- /dev/null
+++ b/contrib/tools/python3/src/Python/hashtable.c
@@ -0,0 +1,417 @@
+/* The implementation of the hash table (_Py_hashtable_t) is based on the
+ cfuhash project:
+ http://sourceforge.net/projects/libcfu/
+
+ Copyright of cfuhash:
+ ----------------------------------
+ Creation date: 2005-06-24 21:22:40
+ Authors: Don
+ Change log:
+
+ Copyright (c) 2005 Don Owens
+ All rights reserved.
+
+ This code is released under the BSD license:
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+
+ * Neither the name of the author nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ ----------------------------------
+*/
+
+#include "Python.h"
+#include "pycore_hashtable.h"
+
+#define HASHTABLE_MIN_SIZE 16
+#define HASHTABLE_HIGH 0.50
+#define HASHTABLE_LOW 0.10
+#define HASHTABLE_REHASH_FACTOR 2.0 / (HASHTABLE_LOW + HASHTABLE_HIGH)
+
+#define BUCKETS_HEAD(SLIST) \
+ ((_Py_hashtable_entry_t *)_Py_SLIST_HEAD(&(SLIST)))
+#define TABLE_HEAD(HT, BUCKET) \
+ ((_Py_hashtable_entry_t *)_Py_SLIST_HEAD(&(HT)->buckets[BUCKET]))
+#define ENTRY_NEXT(ENTRY) \
+ ((_Py_hashtable_entry_t *)_Py_SLIST_ITEM_NEXT(ENTRY))
+
+/* Forward declaration */
+static int hashtable_rehash(_Py_hashtable_t *ht);
+
+static void
+_Py_slist_init(_Py_slist_t *list)
+{
+ list->head = NULL;
+}
+
+
+static void
+_Py_slist_prepend(_Py_slist_t *list, _Py_slist_item_t *item)
+{
+ item->next = list->head;
+ list->head = item;
+}
+
+
+static void
+_Py_slist_remove(_Py_slist_t *list, _Py_slist_item_t *previous,
+ _Py_slist_item_t *item)
+{
+ if (previous != NULL)
+ previous->next = item->next;
+ else
+ list->head = item->next;
+}
+
+
+Py_uhash_t
+_Py_hashtable_hash_ptr(const void *key)
+{
+ return (Py_uhash_t)_Py_HashPointerRaw(key);
+}
+
+
+int
+_Py_hashtable_compare_direct(const void *key1, const void *key2)
+{
+ return (key1 == key2);
+}
+
+
+/* makes sure the real size of the buckets array is a power of 2 */
+static size_t
+round_size(size_t s)
+{
+ size_t i;
+ if (s < HASHTABLE_MIN_SIZE)
+ return HASHTABLE_MIN_SIZE;
+ i = 1;
+ while (i < s)
+ i <<= 1;
+ return i;
+}
+
+
+size_t
+_Py_hashtable_size(const _Py_hashtable_t *ht)
+{
+ size_t size = sizeof(_Py_hashtable_t);
+ /* buckets */
+ size += ht->nbuckets * sizeof(_Py_hashtable_entry_t *);
+ /* entries */
+ size += ht->nentries * sizeof(_Py_hashtable_entry_t);
+ return size;
+}
+
+
+_Py_hashtable_entry_t *
+_Py_hashtable_get_entry_generic(_Py_hashtable_t *ht, const void *key)
+{
+ Py_uhash_t key_hash = ht->hash_func(key);
+ size_t index = key_hash & (ht->nbuckets - 1);
+ _Py_hashtable_entry_t *entry = TABLE_HEAD(ht, index);
+ while (1) {
+ if (entry == NULL) {
+ return NULL;
+ }
+ if (entry->key_hash == key_hash && ht->compare_func(key, entry->key)) {
+ break;
+ }
+ entry = ENTRY_NEXT(entry);
+ }
+ return entry;
+}
+
+
+// Specialized for:
+// hash_func == _Py_hashtable_hash_ptr
+// compare_func == _Py_hashtable_compare_direct
+static _Py_hashtable_entry_t *
+_Py_hashtable_get_entry_ptr(_Py_hashtable_t *ht, const void *key)
+{
+ Py_uhash_t key_hash = _Py_hashtable_hash_ptr(key);
+ size_t index = key_hash & (ht->nbuckets - 1);
+ _Py_hashtable_entry_t *entry = TABLE_HEAD(ht, index);
+ while (1) {
+ if (entry == NULL) {
+ return NULL;
+ }
+ // Compare directly keys (ignore entry->key_hash)
+ if (entry->key == key) {
+ break;
+ }
+ entry = ENTRY_NEXT(entry);
+ }
+ return entry;
+}
+
+
+void*
+_Py_hashtable_steal(_Py_hashtable_t *ht, const void *key)
+{
+ Py_uhash_t key_hash = ht->hash_func(key);
+ size_t index = key_hash & (ht->nbuckets - 1);
+
+ _Py_hashtable_entry_t *entry = TABLE_HEAD(ht, index);
+ _Py_hashtable_entry_t *previous = NULL;
+ while (1) {
+ if (entry == NULL) {
+ // not found
+ return NULL;
+ }
+ if (entry->key_hash == key_hash && ht->compare_func(key, entry->key)) {
+ break;
+ }
+ previous = entry;
+ entry = ENTRY_NEXT(entry);
+ }
+
+ _Py_slist_remove(&ht->buckets[index], (_Py_slist_item_t *)previous,
+ (_Py_slist_item_t *)entry);
+ ht->nentries--;
+
+ void *value = entry->value;
+ ht->alloc.free(entry);
+
+ if ((float)ht->nentries / (float)ht->nbuckets < HASHTABLE_LOW) {
+ // Ignore failure: error cannot be reported to the caller
+ hashtable_rehash(ht);
+ }
+ return value;
+}
+
+
+int
+_Py_hashtable_set(_Py_hashtable_t *ht, const void *key, void *value)
+{
+ _Py_hashtable_entry_t *entry;
+
+#ifndef NDEBUG
+ /* Don't write the assertion on a single line because it is interesting
+ to know the duplicated entry if the assertion failed. The entry can
+ be read using a debugger. */
+ entry = ht->get_entry_func(ht, key);
+ assert(entry == NULL);
+#endif
+
+
+ entry = ht->alloc.malloc(sizeof(_Py_hashtable_entry_t));
+ if (entry == NULL) {
+ /* memory allocation failed */
+ return -1;
+ }
+
+ entry->key_hash = ht->hash_func(key);
+ entry->key = (void *)key;
+ entry->value = value;
+
+ ht->nentries++;
+ if ((float)ht->nentries / (float)ht->nbuckets > HASHTABLE_HIGH) {
+ if (hashtable_rehash(ht) < 0) {
+ ht->nentries--;
+ ht->alloc.free(entry);
+ return -1;
+ }
+ }
+
+ size_t index = entry->key_hash & (ht->nbuckets - 1);
+ _Py_slist_prepend(&ht->buckets[index], (_Py_slist_item_t*)entry);
+ return 0;
+}
+
+
+void*
+_Py_hashtable_get(_Py_hashtable_t *ht, const void *key)
+{
+ _Py_hashtable_entry_t *entry = ht->get_entry_func(ht, key);
+ if (entry != NULL) {
+ return entry->value;
+ }
+ else {
+ return NULL;
+ }
+}
+
+
+int
+_Py_hashtable_foreach(_Py_hashtable_t *ht,
+ _Py_hashtable_foreach_func func,
+ void *user_data)
+{
+ for (size_t hv = 0; hv < ht->nbuckets; hv++) {
+ _Py_hashtable_entry_t *entry = TABLE_HEAD(ht, hv);
+ while (entry != NULL) {
+ int res = func(ht, entry->key, entry->value, user_data);
+ if (res) {
+ return res;
+ }
+ entry = ENTRY_NEXT(entry);
+ }
+ }
+ return 0;
+}
+
+
+static int
+hashtable_rehash(_Py_hashtable_t *ht)
+{
+ size_t new_size = round_size((size_t)(ht->nentries * HASHTABLE_REHASH_FACTOR));
+ if (new_size == ht->nbuckets) {
+ return 0;
+ }
+
+ size_t buckets_size = new_size * sizeof(ht->buckets[0]);
+ _Py_slist_t *new_buckets = ht->alloc.malloc(buckets_size);
+ if (new_buckets == NULL) {
+ /* memory allocation failed */
+ return -1;
+ }
+ memset(new_buckets, 0, buckets_size);
+
+ for (size_t bucket = 0; bucket < ht->nbuckets; bucket++) {
+ _Py_hashtable_entry_t *entry = BUCKETS_HEAD(ht->buckets[bucket]);
+ while (entry != NULL) {
+ assert(ht->hash_func(entry->key) == entry->key_hash);
+ _Py_hashtable_entry_t *next = ENTRY_NEXT(entry);
+ size_t entry_index = entry->key_hash & (new_size - 1);
+
+ _Py_slist_prepend(&new_buckets[entry_index], (_Py_slist_item_t*)entry);
+
+ entry = next;
+ }
+ }
+
+ ht->alloc.free(ht->buckets);
+ ht->nbuckets = new_size;
+ ht->buckets = new_buckets;
+ return 0;
+}
+
+
+_Py_hashtable_t *
+_Py_hashtable_new_full(_Py_hashtable_hash_func hash_func,
+ _Py_hashtable_compare_func compare_func,
+ _Py_hashtable_destroy_func key_destroy_func,
+ _Py_hashtable_destroy_func value_destroy_func,
+ _Py_hashtable_allocator_t *allocator)
+{
+ _Py_hashtable_allocator_t alloc;
+ if (allocator == NULL) {
+ alloc.malloc = PyMem_Malloc;
+ alloc.free = PyMem_Free;
+ }
+ else {
+ alloc = *allocator;
+ }
+
+ _Py_hashtable_t *ht = (_Py_hashtable_t *)alloc.malloc(sizeof(_Py_hashtable_t));
+ if (ht == NULL) {
+ return ht;
+ }
+
+ ht->nbuckets = HASHTABLE_MIN_SIZE;
+ ht->nentries = 0;
+
+ size_t buckets_size = ht->nbuckets * sizeof(ht->buckets[0]);
+ ht->buckets = alloc.malloc(buckets_size);
+ if (ht->buckets == NULL) {
+ alloc.free(ht);
+ return NULL;
+ }
+ memset(ht->buckets, 0, buckets_size);
+
+ ht->get_entry_func = _Py_hashtable_get_entry_generic;
+ ht->hash_func = hash_func;
+ ht->compare_func = compare_func;
+ ht->key_destroy_func = key_destroy_func;
+ ht->value_destroy_func = value_destroy_func;
+ ht->alloc = alloc;
+ if (ht->hash_func == _Py_hashtable_hash_ptr
+ && ht->compare_func == _Py_hashtable_compare_direct)
+ {
+ ht->get_entry_func = _Py_hashtable_get_entry_ptr;
+ }
+ return ht;
+}
+
+
+_Py_hashtable_t *
+_Py_hashtable_new(_Py_hashtable_hash_func hash_func,
+ _Py_hashtable_compare_func compare_func)
+{
+ return _Py_hashtable_new_full(hash_func, compare_func,
+ NULL, NULL, NULL);
+}
+
+
+static void
+_Py_hashtable_destroy_entry(_Py_hashtable_t *ht, _Py_hashtable_entry_t *entry)
+{
+ if (ht->key_destroy_func) {
+ ht->key_destroy_func(entry->key);
+ }
+ if (ht->value_destroy_func) {
+ ht->value_destroy_func(entry->value);
+ }
+ ht->alloc.free(entry);
+}
+
+
+void
+_Py_hashtable_clear(_Py_hashtable_t *ht)
+{
+ for (size_t i=0; i < ht->nbuckets; i++) {
+ _Py_hashtable_entry_t *entry = TABLE_HEAD(ht, i);
+ while (entry != NULL) {
+ _Py_hashtable_entry_t *next = ENTRY_NEXT(entry);
+ _Py_hashtable_destroy_entry(ht, entry);
+ entry = next;
+ }
+ _Py_slist_init(&ht->buckets[i]);
+ }
+ ht->nentries = 0;
+ // Ignore failure: clear function is not expected to fail
+ // because of a memory allocation failure.
+ (void)hashtable_rehash(ht);
+}
+
+
+void
+_Py_hashtable_destroy(_Py_hashtable_t *ht)
+{
+ for (size_t i = 0; i < ht->nbuckets; i++) {
+ _Py_hashtable_entry_t *entry = TABLE_HEAD(ht, i);
+ while (entry) {
+ _Py_hashtable_entry_t *entry_next = ENTRY_NEXT(entry);
+ _Py_hashtable_destroy_entry(ht, entry);
+ entry = entry_next;
+ }
+ }
+
+ ht->alloc.free(ht->buckets);
+ ht->alloc.free(ht);
+}
diff --git a/contrib/tools/python3/src/Python/import.c b/contrib/tools/python3/src/Python/import.c
new file mode 100644
index 00000000000..e4dbf4b0d8c
--- /dev/null
+++ b/contrib/tools/python3/src/Python/import.c
@@ -0,0 +1,2512 @@
+/* Module definition and import implementation */
+
+#include "Python.h"
+
+#include "Python-ast.h"
+#undef Yield /* undefine macro conflicting with <winbase.h> */
+#include "pycore_initconfig.h"
+#include "pycore_pyerrors.h"
+#include "pycore_pyhash.h"
+#include "pycore_pylifecycle.h"
+#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
+#include "pycore_interp.h" // _PyInterpreterState_ClearModules()
+#include "pycore_pystate.h" // _PyInterpreterState_GET()
+#include "pycore_sysmodule.h"
+#include "errcode.h"
+#include "marshal.h"
+#include "code.h"
+#include "importdl.h"
+#include "pydtrace.h"
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CACHEDIR "__pycache__"
+
+/* Forward references */
+static PyObject *import_add_module(PyThreadState *tstate, PyObject *name);
+
+/* See _PyImport_FixupExtensionObject() below */
+static PyObject *extensions = NULL;
+
+/* This table is defined in config.c: */
+extern struct _inittab _PyImport_Inittab[];
+
+struct _inittab *PyImport_Inittab = _PyImport_Inittab;
+static struct _inittab *inittab_copy = NULL;
+
+_Py_IDENTIFIER(__path__);
+_Py_IDENTIFIER(__spec__);
+
+/*[clinic input]
+module _imp
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9c332475d8686284]*/
+
+#include "clinic/import.c.h"
+
+/* Initialize things */
+
+PyStatus
+_PyImportHooks_Init(PyThreadState *tstate)
+{
+ PyObject *v, *path_hooks = NULL;
+ int err = 0;
+
+ /* adding sys.path_hooks and sys.path_importer_cache */
+ v = PyList_New(0);
+ if (v == NULL)
+ goto error;
+ err = PySys_SetObject("meta_path", v);
+ Py_DECREF(v);
+ if (err)
+ goto error;
+ v = PyDict_New();
+ if (v == NULL)
+ goto error;
+ err = PySys_SetObject("path_importer_cache", v);
+ Py_DECREF(v);
+ if (err)
+ goto error;
+ path_hooks = PyList_New(0);
+ if (path_hooks == NULL)
+ goto error;
+ err = PySys_SetObject("path_hooks", path_hooks);
+ if (err) {
+ goto error;
+ }
+ Py_DECREF(path_hooks);
+ return _PyStatus_OK();
+
+ error:
+ _PyErr_Print(tstate);
+ return _PyStatus_ERR("initializing sys.meta_path, sys.path_hooks, "
+ "or path_importer_cache failed");
+}
+
+PyStatus
+_PyImportZip_Init(PyThreadState *tstate)
+{
+ PyObject *path_hooks, *zipimport;
+ int err = 0;
+
+ path_hooks = PySys_GetObject("path_hooks");
+ if (path_hooks == NULL) {
+ _PyErr_SetString(tstate, PyExc_RuntimeError,
+ "unable to get sys.path_hooks");
+ goto error;
+ }
+
+ int verbose = _PyInterpreterState_GetConfig(tstate->interp)->verbose;
+ if (verbose) {
+ PySys_WriteStderr("# installing zipimport hook\n");
+ }
+
+ zipimport = PyImport_ImportModule("zipimport");
+ if (zipimport == NULL) {
+ _PyErr_Clear(tstate); /* No zip import module -- okay */
+ if (verbose) {
+ PySys_WriteStderr("# can't import zipimport\n");
+ }
+ }
+ else {
+ _Py_IDENTIFIER(zipimporter);
+ PyObject *zipimporter = _PyObject_GetAttrId(zipimport,
+ &PyId_zipimporter);
+ Py_DECREF(zipimport);
+ if (zipimporter == NULL) {
+ _PyErr_Clear(tstate); /* No zipimporter object -- okay */
+ if (verbose) {
+ PySys_WriteStderr("# can't import zipimport.zipimporter\n");
+ }
+ }
+ else {
+ /* sys.path_hooks.insert(0, zipimporter) */
+ err = PyList_Insert(path_hooks, 0, zipimporter);
+ Py_DECREF(zipimporter);
+ if (err < 0) {
+ goto error;
+ }
+ if (verbose) {
+ PySys_WriteStderr("# installed zipimport hook\n");
+ }
+ }
+ }
+
+ return _PyStatus_OK();
+
+ error:
+ PyErr_Print();
+ return _PyStatus_ERR("initializing zipimport failed");
+}
+
+/* Locking primitives to prevent parallel imports of the same module
+ in different threads to return with a partially loaded module.
+ These calls are serialized by the global interpreter lock. */
+
+static PyThread_type_lock import_lock = 0;
+static unsigned long import_lock_thread = PYTHREAD_INVALID_THREAD_ID;
+static int import_lock_level = 0;
+
+void
+_PyImport_AcquireLock(void)
+{
+ unsigned long me = PyThread_get_thread_ident();
+ if (me == PYTHREAD_INVALID_THREAD_ID)
+ return; /* Too bad */
+ if (import_lock == NULL) {
+ import_lock = PyThread_allocate_lock();
+ if (import_lock == NULL)
+ return; /* Nothing much we can do. */
+ }
+ if (import_lock_thread == me) {
+ import_lock_level++;
+ return;
+ }
+ if (import_lock_thread != PYTHREAD_INVALID_THREAD_ID ||
+ !PyThread_acquire_lock(import_lock, 0))
+ {
+ PyThreadState *tstate = PyEval_SaveThread();
+ PyThread_acquire_lock(import_lock, 1);
+ PyEval_RestoreThread(tstate);
+ }
+ assert(import_lock_level == 0);
+ import_lock_thread = me;
+ import_lock_level = 1;
+}
+
+int
+_PyImport_ReleaseLock(void)
+{
+ unsigned long me = PyThread_get_thread_ident();
+ if (me == PYTHREAD_INVALID_THREAD_ID || import_lock == NULL)
+ return 0; /* Too bad */
+ if (import_lock_thread != me)
+ return -1;
+ import_lock_level--;
+ assert(import_lock_level >= 0);
+ if (import_lock_level == 0) {
+ import_lock_thread = PYTHREAD_INVALID_THREAD_ID;
+ PyThread_release_lock(import_lock);
+ }
+ return 1;
+}
+
+#ifdef HAVE_FORK
+/* This function is called from PyOS_AfterFork_Child to ensure that newly
+ created child processes do not share locks with the parent.
+ We now acquire the import lock around fork() calls but on some platforms
+ (Solaris 9 and earlier? see isue7242) that still left us with problems. */
+
+void
+_PyImport_ReInitLock(void)
+{
+ if (import_lock != NULL) {
+ if (_PyThread_at_fork_reinit(&import_lock) < 0) {
+ _Py_FatalErrorFunc(__func__, "failed to create a new lock");
+ }
+ }
+ if (import_lock_level > 1) {
+ /* Forked as a side effect of import */
+ unsigned long me = PyThread_get_thread_ident();
+ /* The following could fail if the lock is already held, but forking as
+ a side-effect of an import is a) rare, b) nuts, and c) difficult to
+ do thanks to the lock only being held when doing individual module
+ locks per import. */
+ PyThread_acquire_lock(import_lock, NOWAIT_LOCK);
+ import_lock_thread = me;
+ import_lock_level--;
+ } else {
+ import_lock_thread = PYTHREAD_INVALID_THREAD_ID;
+ import_lock_level = 0;
+ }
+}
+#endif
+
+/*[clinic input]
+_imp.lock_held
+
+Return True if the import lock is currently held, else False.
+
+On platforms without threads, return False.
+[clinic start generated code]*/
+
+static PyObject *
+_imp_lock_held_impl(PyObject *module)
+/*[clinic end generated code: output=8b89384b5e1963fc input=9b088f9b217d9bdf]*/
+{
+ return PyBool_FromLong(import_lock_thread != PYTHREAD_INVALID_THREAD_ID);
+}
+
+/*[clinic input]
+_imp.acquire_lock
+
+Acquires the interpreter's import lock for the current thread.
+
+This lock should be used by import hooks to ensure thread-safety when importing
+modules. On platforms without threads, this function does nothing.
+[clinic start generated code]*/
+
+static PyObject *
+_imp_acquire_lock_impl(PyObject *module)
+/*[clinic end generated code: output=1aff58cb0ee1b026 input=4a2d4381866d5fdc]*/
+{
+ _PyImport_AcquireLock();
+ Py_RETURN_NONE;
+}
+
+/*[clinic input]
+_imp.release_lock
+
+Release the interpreter's import lock.
+
+On platforms without threads, this function does nothing.
+[clinic start generated code]*/
+
+static PyObject *
+_imp_release_lock_impl(PyObject *module)
+/*[clinic end generated code: output=7faab6d0be178b0a input=934fb11516dd778b]*/
+{
+ if (_PyImport_ReleaseLock() < 0) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "not holding the import lock");
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+void
+_PyImport_Fini(void)
+{
+ Py_CLEAR(extensions);
+ if (import_lock != NULL) {
+ PyThread_free_lock(import_lock);
+ import_lock = NULL;
+ }
+}
+
+void
+_PyImport_Fini2(void)
+{
+ /* Use the same memory allocator than PyImport_ExtendInittab(). */
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ // Reset PyImport_Inittab
+ PyImport_Inittab = _PyImport_Inittab;
+
+ /* Free memory allocated by PyImport_ExtendInittab() */
+ PyMem_RawFree(inittab_copy);
+ inittab_copy = NULL;
+
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+}
+
+/* Helper for sys */
+
+PyObject *
+PyImport_GetModuleDict(void)
+{
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ if (interp->modules == NULL) {
+ Py_FatalError("interpreter has no modules dictionary");
+ }
+ return interp->modules;
+}
+
+/* In some corner cases it is important to be sure that the import
+ machinery has been initialized (or not cleaned up yet). For
+ example, see issue #4236 and PyModule_Create2(). */
+
+int
+_PyImport_IsInitialized(PyInterpreterState *interp)
+{
+ if (interp->modules == NULL)
+ return 0;
+ return 1;
+}
+
+PyObject *
+_PyImport_GetModuleId(struct _Py_Identifier *nameid)
+{
+ PyObject *name = _PyUnicode_FromId(nameid); /* borrowed */
+ if (name == NULL) {
+ return NULL;
+ }
+ return PyImport_GetModule(name);
+}
+
+int
+_PyImport_SetModule(PyObject *name, PyObject *m)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyObject *modules = tstate->interp->modules;
+ return PyObject_SetItem(modules, name, m);
+}
+
+int
+_PyImport_SetModuleString(const char *name, PyObject *m)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyObject *modules = tstate->interp->modules;
+ return PyMapping_SetItemString(modules, name, m);
+}
+
+static PyObject *
+import_get_module(PyThreadState *tstate, PyObject *name)
+{
+ PyObject *modules = tstate->interp->modules;
+ if (modules == NULL) {
+ _PyErr_SetString(tstate, PyExc_RuntimeError,
+ "unable to get sys.modules");
+ return NULL;
+ }
+
+ PyObject *m;
+ Py_INCREF(modules);
+ if (PyDict_CheckExact(modules)) {
+ m = PyDict_GetItemWithError(modules, name); /* borrowed */
+ Py_XINCREF(m);
+ }
+ else {
+ m = PyObject_GetItem(modules, name);
+ if (m == NULL && _PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
+ _PyErr_Clear(tstate);
+ }
+ }
+ Py_DECREF(modules);
+ return m;
+}
+
+
+static int
+import_ensure_initialized(PyThreadState *tstate, PyObject *mod, PyObject *name)
+{
+ PyInterpreterState *interp = tstate->interp;
+ PyObject *spec;
+
+ _Py_IDENTIFIER(_lock_unlock_module);
+
+ /* Optimization: only call _bootstrap._lock_unlock_module() if
+ __spec__._initializing is true.
+ NOTE: because of this, initializing must be set *before*
+ stuffing the new module in sys.modules.
+ */
+ spec = _PyObject_GetAttrId(mod, &PyId___spec__);
+ int busy = _PyModuleSpec_IsInitializing(spec);
+ Py_XDECREF(spec);
+ if (busy) {
+ /* Wait until module is done importing. */
+ PyObject *value = _PyObject_CallMethodIdOneArg(
+ interp->importlib, &PyId__lock_unlock_module, name);
+ if (value == NULL) {
+ return -1;
+ }
+ Py_DECREF(value);
+ }
+ return 0;
+}
+
+
+/* List of names to clear in sys */
+static const char * const sys_deletes[] = {
+ "path", "argv", "ps1", "ps2",
+ "last_type", "last_value", "last_traceback",
+ "path_hooks", "path_importer_cache", "meta_path",
+ "__interactivehook__",
+ NULL
+};
+
+static const char * const sys_files[] = {
+ "stdin", "__stdin__",
+ "stdout", "__stdout__",
+ "stderr", "__stderr__",
+ NULL
+};
+
+/* Un-initialize things, as good as we can */
+
+void
+_PyImport_Cleanup(PyThreadState *tstate)
+{
+ PyInterpreterState *interp = tstate->interp;
+ PyObject *modules = interp->modules;
+ if (modules == NULL) {
+ /* Already done */
+ return;
+ }
+
+ /* Delete some special variables first. These are common
+ places where user values hide and people complain when their
+ destructors fail. Since the modules containing them are
+ deleted *last* of all, they would come too late in the normal
+ destruction order. Sigh. */
+
+ /* XXX Perhaps these precautions are obsolete. Who knows? */
+
+ int verbose = _PyInterpreterState_GetConfig(interp)->verbose;
+ if (verbose) {
+ PySys_WriteStderr("# clear builtins._\n");
+ }
+ if (PyDict_SetItemString(interp->builtins, "_", Py_None) < 0) {
+ PyErr_WriteUnraisable(NULL);
+ }
+
+ const char * const *p;
+ for (p = sys_deletes; *p != NULL; p++) {
+ if (verbose) {
+ PySys_WriteStderr("# clear sys.%s\n", *p);
+ }
+ if (PyDict_SetItemString(interp->sysdict, *p, Py_None) < 0) {
+ PyErr_WriteUnraisable(NULL);
+ }
+ }
+ for (p = sys_files; *p != NULL; p+=2) {
+ if (verbose) {
+ PySys_WriteStderr("# restore sys.%s\n", *p);
+ }
+ PyObject *value = _PyDict_GetItemStringWithError(interp->sysdict,
+ *(p+1));
+ if (value == NULL) {
+ if (_PyErr_Occurred(tstate)) {
+ PyErr_WriteUnraisable(NULL);
+ }
+ value = Py_None;
+ }
+ if (PyDict_SetItemString(interp->sysdict, *p, value) < 0) {
+ PyErr_WriteUnraisable(NULL);
+ }
+ }
+
+ /* We prepare a list which will receive (name, weakref) tuples of
+ modules when they are removed from sys.modules. The name is used
+ for diagnosis messages (in verbose mode), while the weakref helps
+ detect those modules which have been held alive. */
+ PyObject *weaklist = PyList_New(0);
+ if (weaklist == NULL) {
+ PyErr_WriteUnraisable(NULL);
+ }
+
+#define STORE_MODULE_WEAKREF(name, mod) \
+ if (weaklist != NULL) { \
+ PyObject *wr = PyWeakref_NewRef(mod, NULL); \
+ if (wr) { \
+ PyObject *tup = PyTuple_Pack(2, name, wr); \
+ if (!tup || PyList_Append(weaklist, tup) < 0) { \
+ PyErr_WriteUnraisable(NULL); \
+ } \
+ Py_XDECREF(tup); \
+ Py_DECREF(wr); \
+ } \
+ else { \
+ PyErr_WriteUnraisable(NULL); \
+ } \
+ }
+#define CLEAR_MODULE(name, mod) \
+ if (PyModule_Check(mod)) { \
+ if (verbose && PyUnicode_Check(name)) { \
+ PySys_FormatStderr("# cleanup[2] removing %U\n", name); \
+ } \
+ STORE_MODULE_WEAKREF(name, mod); \
+ if (PyObject_SetItem(modules, name, Py_None) < 0) { \
+ PyErr_WriteUnraisable(NULL); \
+ } \
+ }
+
+ /* Remove all modules from sys.modules, hoping that garbage collection
+ can reclaim most of them. */
+ if (PyDict_CheckExact(modules)) {
+ Py_ssize_t pos = 0;
+ PyObject *key, *value;
+ while (PyDict_Next(modules, &pos, &key, &value)) {
+ CLEAR_MODULE(key, value);
+ }
+ }
+ else {
+ PyObject *iterator = PyObject_GetIter(modules);
+ if (iterator == NULL) {
+ PyErr_WriteUnraisable(NULL);
+ }
+ else {
+ PyObject *key;
+ while ((key = PyIter_Next(iterator))) {
+ PyObject *value = PyObject_GetItem(modules, key);
+ if (value == NULL) {
+ PyErr_WriteUnraisable(NULL);
+ continue;
+ }
+ CLEAR_MODULE(key, value);
+ Py_DECREF(value);
+ Py_DECREF(key);
+ }
+ if (PyErr_Occurred()) {
+ PyErr_WriteUnraisable(NULL);
+ }
+ Py_DECREF(iterator);
+ }
+ }
+
+ /* Clear the modules dict. */
+ if (PyDict_CheckExact(modules)) {
+ PyDict_Clear(modules);
+ }
+ else {
+ _Py_IDENTIFIER(clear);
+ if (_PyObject_CallMethodIdNoArgs(modules, &PyId_clear) == NULL) {
+ PyErr_WriteUnraisable(NULL);
+ }
+ }
+ /* Restore the original builtins dict, to ensure that any
+ user data gets cleared. */
+ PyObject *dict = PyDict_Copy(interp->builtins);
+ if (dict == NULL) {
+ PyErr_WriteUnraisable(NULL);
+ }
+ PyDict_Clear(interp->builtins);
+ if (PyDict_Update(interp->builtins, interp->builtins_copy)) {
+ _PyErr_Clear(tstate);
+ }
+ Py_XDECREF(dict);
+ /* Collect references */
+ _PyGC_CollectNoFail();
+ /* Dump GC stats before it's too late, since it uses the warnings
+ machinery. */
+ _PyGC_DumpShutdownStats(tstate);
+
+ /* Now, if there are any modules left alive, clear their globals to
+ minimize potential leaks. All C extension modules actually end
+ up here, since they are kept alive in the interpreter state.
+
+ The special treatment of "builtins" here is because even
+ when it's not referenced as a module, its dictionary is
+ referenced by almost every module's __builtins__. Since
+ deleting a module clears its dictionary (even if there are
+ references left to it), we need to delete the "builtins"
+ module last. Likewise, we don't delete sys until the very
+ end because it is implicitly referenced (e.g. by print). */
+ if (weaklist != NULL) {
+ Py_ssize_t i;
+ /* Since dict is ordered in CPython 3.6+, modules are saved in
+ importing order. First clear modules imported later. */
+ for (i = PyList_GET_SIZE(weaklist) - 1; i >= 0; i--) {
+ PyObject *tup = PyList_GET_ITEM(weaklist, i);
+ PyObject *name = PyTuple_GET_ITEM(tup, 0);
+ PyObject *mod = PyWeakref_GET_OBJECT(PyTuple_GET_ITEM(tup, 1));
+ if (mod == Py_None)
+ continue;
+ assert(PyModule_Check(mod));
+ dict = PyModule_GetDict(mod);
+ if (dict == interp->builtins || dict == interp->sysdict)
+ continue;
+ Py_INCREF(mod);
+ if (verbose && PyUnicode_Check(name)) {
+ PySys_FormatStderr("# cleanup[3] wiping %U\n", name);
+ }
+ _PyModule_Clear(mod);
+ Py_DECREF(mod);
+ }
+ Py_DECREF(weaklist);
+ }
+
+ /* Next, delete sys and builtins (in that order) */
+ if (verbose) {
+ PySys_FormatStderr("# cleanup[3] wiping sys\n");
+ }
+ _PyModule_ClearDict(interp->sysdict);
+ if (verbose) {
+ PySys_FormatStderr("# cleanup[3] wiping builtins\n");
+ }
+ _PyModule_ClearDict(interp->builtins);
+
+ /* Clear module dict copies stored in the interpreter state */
+ _PyInterpreterState_ClearModules(interp);
+
+ /* Clear and delete the modules directory. Actual modules will
+ still be there only if imported during the execution of some
+ destructor. */
+ interp->modules = NULL;
+ Py_DECREF(modules);
+
+ /* Once more */
+ _PyGC_CollectNoFail();
+
+#undef CLEAR_MODULE
+#undef STORE_MODULE_WEAKREF
+}
+
+
+/* Helper for pythonrun.c -- return magic number and tag. */
+
+long
+PyImport_GetMagicNumber(void)
+{
+ long res;
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ PyObject *external, *pyc_magic;
+
+ external = PyObject_GetAttrString(interp->importlib, "_bootstrap_external");
+ if (external == NULL)
+ return -1;
+ pyc_magic = PyObject_GetAttrString(external, "_RAW_MAGIC_NUMBER");
+ Py_DECREF(external);
+ if (pyc_magic == NULL)
+ return -1;
+ res = PyLong_AsLong(pyc_magic);
+ Py_DECREF(pyc_magic);
+ return res;
+}
+
+
+extern const char * _PySys_ImplCacheTag;
+
+const char *
+PyImport_GetMagicTag(void)
+{
+ return _PySys_ImplCacheTag;
+}
+
+
+/* Magic for extension modules (built-in as well as dynamically
+ loaded). To prevent initializing an extension module more than
+ once, we keep a static dictionary 'extensions' keyed by the tuple
+ (module name, module name) (for built-in modules) or by
+ (filename, module name) (for dynamically loaded modules), containing these
+ modules. A copy of the module's dictionary is stored by calling
+ _PyImport_FixupExtensionObject() immediately after the module initialization
+ function succeeds. A copy can be retrieved from there by calling
+ _PyImport_FindExtensionObject().
+
+ Modules which do support multiple initialization set their m_size
+ field to a non-negative number (indicating the size of the
+ module-specific state). They are still recorded in the extensions
+ dictionary, to avoid loading shared libraries twice.
+*/
+
+int
+_PyImport_FixupExtensionObject(PyObject *mod, PyObject *name,
+ PyObject *filename, PyObject *modules)
+{
+ if (mod == NULL || !PyModule_Check(mod)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+
+ struct PyModuleDef *def = PyModule_GetDef(mod);
+ if (!def) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (PyObject_SetItem(modules, name, mod) < 0) {
+ return -1;
+ }
+ if (_PyState_AddModule(tstate, mod, def) < 0) {
+ PyMapping_DelItem(modules, name);
+ return -1;
+ }
+
+ // bpo-44050: Extensions and def->m_base.m_copy can be updated
+ // when the extension module doesn't support sub-interpreters.
+ if (_Py_IsMainInterpreter(tstate) || def->m_size == -1) {
+ if (def->m_size == -1) {
+ if (def->m_base.m_copy) {
+ /* Somebody already imported the module,
+ likely under a different name.
+ XXX this should really not happen. */
+ Py_CLEAR(def->m_base.m_copy);
+ }
+ PyObject *dict = PyModule_GetDict(mod);
+ if (dict == NULL) {
+ return -1;
+ }
+ def->m_base.m_copy = PyDict_Copy(dict);
+ if (def->m_base.m_copy == NULL) {
+ return -1;
+ }
+ }
+
+ if (extensions == NULL) {
+ extensions = PyDict_New();
+ if (extensions == NULL) {
+ return -1;
+ }
+ }
+
+ PyObject *key = PyTuple_Pack(2, filename, name);
+ if (key == NULL) {
+ return -1;
+ }
+ int res = PyDict_SetItem(extensions, key, (PyObject *)def);
+ Py_DECREF(key);
+ if (res < 0) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int
+_PyImport_FixupBuiltin(PyObject *mod, const char *name, PyObject *modules)
+{
+ int res;
+ PyObject *nameobj;
+ nameobj = PyUnicode_InternFromString(name);
+ if (nameobj == NULL)
+ return -1;
+ res = _PyImport_FixupExtensionObject(mod, nameobj, nameobj, modules);
+ Py_DECREF(nameobj);
+ return res;
+}
+
+static PyObject *
+import_find_extension(PyThreadState *tstate, PyObject *name,
+ PyObject *filename)
+{
+ if (extensions == NULL) {
+ return NULL;
+ }
+
+ PyObject *key = PyTuple_Pack(2, filename, name);
+ if (key == NULL) {
+ return NULL;
+ }
+ PyModuleDef* def = (PyModuleDef *)PyDict_GetItemWithError(extensions, key);
+ Py_DECREF(key);
+ if (def == NULL) {
+ return NULL;
+ }
+
+ PyObject *mod, *mdict;
+ PyObject *modules = tstate->interp->modules;
+
+ if (def->m_size == -1) {
+ /* Module does not support repeated initialization */
+ if (def->m_base.m_copy == NULL)
+ return NULL;
+ mod = import_add_module(tstate, name);
+ if (mod == NULL)
+ return NULL;
+ mdict = PyModule_GetDict(mod);
+ if (mdict == NULL)
+ return NULL;
+ if (PyDict_Update(mdict, def->m_base.m_copy))
+ return NULL;
+ }
+ else {
+ if (def->m_base.m_init == NULL)
+ return NULL;
+ mod = def->m_base.m_init();
+ if (mod == NULL)
+ return NULL;
+ if (PyObject_SetItem(modules, name, mod) == -1) {
+ Py_DECREF(mod);
+ return NULL;
+ }
+ Py_DECREF(mod);
+ }
+ if (_PyState_AddModule(tstate, mod, def) < 0) {
+ PyMapping_DelItem(modules, name);
+ return NULL;
+ }
+
+ int verbose = _PyInterpreterState_GetConfig(tstate->interp)->verbose;
+ if (verbose) {
+ PySys_FormatStderr("import %U # previously loaded (%R)\n",
+ name, filename);
+ }
+ return mod;
+}
+
+PyObject *
+_PyImport_FindExtensionObject(PyObject *name, PyObject *filename)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ return import_find_extension(tstate, name, filename);
+}
+
+
+PyObject *
+_PyImport_FindBuiltin(PyThreadState *tstate, const char *name)
+{
+ PyObject *res, *nameobj;
+ nameobj = PyUnicode_InternFromString(name);
+ if (nameobj == NULL)
+ return NULL;
+ res = import_find_extension(tstate, nameobj, nameobj);
+ Py_DECREF(nameobj);
+ return res;
+}
+
+/* Get the module object corresponding to a module name.
+ First check the modules dictionary if there's one there,
+ if not, create a new one and insert it in the modules dictionary.
+ Because the former action is most common, THIS DOES NOT RETURN A
+ 'NEW' REFERENCE! */
+
+static PyObject *
+import_add_module(PyThreadState *tstate, PyObject *name)
+{
+ PyObject *modules = tstate->interp->modules;
+ if (modules == NULL) {
+ _PyErr_SetString(tstate, PyExc_RuntimeError,
+ "no import module dictionary");
+ return NULL;
+ }
+
+ PyObject *m;
+ if (PyDict_CheckExact(modules)) {
+ m = PyDict_GetItemWithError(modules, name);
+ }
+ else {
+ m = PyObject_GetItem(modules, name);
+ // For backward-compatibility we copy the behavior
+ // of PyDict_GetItemWithError().
+ if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
+ _PyErr_Clear(tstate);
+ }
+ }
+ if (_PyErr_Occurred(tstate)) {
+ return NULL;
+ }
+ if (m != NULL && PyModule_Check(m)) {
+ return m;
+ }
+ m = PyModule_NewObject(name);
+ if (m == NULL)
+ return NULL;
+ if (PyObject_SetItem(modules, name, m) != 0) {
+ Py_DECREF(m);
+ return NULL;
+ }
+ Py_DECREF(m); /* Yes, it still exists, in modules! */
+
+ return m;
+}
+
+PyObject *
+PyImport_AddModuleObject(PyObject *name)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ return import_add_module(tstate, name);
+}
+
+
+PyObject *
+PyImport_AddModule(const char *name)
+{
+ PyObject *nameobj = PyUnicode_FromString(name);
+ if (nameobj == NULL) {
+ return NULL;
+ }
+ PyObject *module = PyImport_AddModuleObject(nameobj);
+ Py_DECREF(nameobj);
+ return module;
+}
+
+
+/* Remove name from sys.modules, if it's there.
+ * Can be called with an exception raised.
+ * If fail to remove name a new exception will be chained with the old
+ * exception, otherwise the old exception is preserved.
+ */
+static void
+remove_module(PyThreadState *tstate, PyObject *name)
+{
+ PyObject *type, *value, *traceback;
+ _PyErr_Fetch(tstate, &type, &value, &traceback);
+
+ PyObject *modules = tstate->interp->modules;
+ if (PyDict_CheckExact(modules)) {
+ PyObject *mod = _PyDict_Pop(modules, name, Py_None);
+ Py_XDECREF(mod);
+ }
+ else if (PyMapping_DelItem(modules, name) < 0) {
+ if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
+ _PyErr_Clear(tstate);
+ }
+ }
+
+ _PyErr_ChainExceptions(type, value, traceback);
+}
+
+
+/* Execute a code object in a module and return the module object
+ * WITH INCREMENTED REFERENCE COUNT. If an error occurs, name is
+ * removed from sys.modules, to avoid leaving damaged module objects
+ * in sys.modules. The caller may wish to restore the original
+ * module object (if any) in this case; PyImport_ReloadModule is an
+ * example.
+ *
+ * Note that PyImport_ExecCodeModuleWithPathnames() is the preferred, richer
+ * interface. The other two exist primarily for backward compatibility.
+ */
+PyObject *
+PyImport_ExecCodeModule(const char *name, PyObject *co)
+{
+ return PyImport_ExecCodeModuleWithPathnames(
+ name, co, (char *)NULL, (char *)NULL);
+}
+
+PyObject *
+PyImport_ExecCodeModuleEx(const char *name, PyObject *co, const char *pathname)
+{
+ return PyImport_ExecCodeModuleWithPathnames(
+ name, co, pathname, (char *)NULL);
+}
+
+PyObject *
+PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co,
+ const char *pathname,
+ const char *cpathname)
+{
+ PyObject *m = NULL;
+ PyObject *nameobj, *pathobj = NULL, *cpathobj = NULL, *external= NULL;
+
+ nameobj = PyUnicode_FromString(name);
+ if (nameobj == NULL)
+ return NULL;
+
+ if (cpathname != NULL) {
+ cpathobj = PyUnicode_DecodeFSDefault(cpathname);
+ if (cpathobj == NULL)
+ goto error;
+ }
+ else
+ cpathobj = NULL;
+
+ if (pathname != NULL) {
+ pathobj = PyUnicode_DecodeFSDefault(pathname);
+ if (pathobj == NULL)
+ goto error;
+ }
+ else if (cpathobj != NULL) {
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ _Py_IDENTIFIER(_get_sourcefile);
+
+ if (interp == NULL) {
+ Py_FatalError("no current interpreter");
+ }
+
+ external= PyObject_GetAttrString(interp->importlib,
+ "_bootstrap_external");
+ if (external != NULL) {
+ pathobj = _PyObject_CallMethodIdOneArg(
+ external, &PyId__get_sourcefile, cpathobj);
+ Py_DECREF(external);
+ }
+ if (pathobj == NULL)
+ PyErr_Clear();
+ }
+ else
+ pathobj = NULL;
+
+ m = PyImport_ExecCodeModuleObject(nameobj, co, pathobj, cpathobj);
+error:
+ Py_DECREF(nameobj);
+ Py_XDECREF(pathobj);
+ Py_XDECREF(cpathobj);
+ return m;
+}
+
+static PyObject *
+module_dict_for_exec(PyThreadState *tstate, PyObject *name)
+{
+ _Py_IDENTIFIER(__builtins__);
+ PyObject *m, *d = NULL;
+
+ m = import_add_module(tstate, name);
+ if (m == NULL)
+ return NULL;
+ /* If the module is being reloaded, we get the old module back
+ and re-use its dict to exec the new code. */
+ d = PyModule_GetDict(m);
+ if (_PyDict_GetItemIdWithError(d, &PyId___builtins__) == NULL) {
+ if (_PyErr_Occurred(tstate) ||
+ _PyDict_SetItemId(d, &PyId___builtins__,
+ PyEval_GetBuiltins()) != 0)
+ {
+ remove_module(tstate, name);
+ return NULL;
+ }
+ }
+
+ return d; /* Return a borrowed reference. */
+}
+
+static PyObject *
+exec_code_in_module(PyThreadState *tstate, PyObject *name,
+ PyObject *module_dict, PyObject *code_object)
+{
+ PyObject *v, *m;
+
+ v = PyEval_EvalCode(code_object, module_dict, module_dict);
+ if (v == NULL) {
+ remove_module(tstate, name);
+ return NULL;
+ }
+ Py_DECREF(v);
+
+ m = import_get_module(tstate, name);
+ if (m == NULL && !_PyErr_Occurred(tstate)) {
+ _PyErr_Format(tstate, PyExc_ImportError,
+ "Loaded module %R not found in sys.modules",
+ name);
+ }
+
+ return m;
+}
+
+PyObject*
+PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname,
+ PyObject *cpathname)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyObject *d, *external, *res;
+ _Py_IDENTIFIER(_fix_up_module);
+
+ d = module_dict_for_exec(tstate, name);
+ if (d == NULL) {
+ return NULL;
+ }
+
+ if (pathname == NULL) {
+ pathname = ((PyCodeObject *)co)->co_filename;
+ }
+ external = PyObject_GetAttrString(tstate->interp->importlib,
+ "_bootstrap_external");
+ if (external == NULL)
+ return NULL;
+ res = _PyObject_CallMethodIdObjArgs(external,
+ &PyId__fix_up_module,
+ d, name, pathname, cpathname, NULL);
+ Py_DECREF(external);
+ if (res != NULL) {
+ Py_DECREF(res);
+ res = exec_code_in_module(tstate, name, d, co);
+ }
+ return res;
+}
+
+
+static void
+update_code_filenames(PyCodeObject *co, PyObject *oldname, PyObject *newname)
+{
+ PyObject *constants, *tmp;
+ Py_ssize_t i, n;
+
+ if (PyUnicode_Compare(co->co_filename, oldname))
+ return;
+
+ Py_INCREF(newname);
+ Py_XSETREF(co->co_filename, newname);
+
+ constants = co->co_consts;
+ n = PyTuple_GET_SIZE(constants);
+ for (i = 0; i < n; i++) {
+ tmp = PyTuple_GET_ITEM(constants, i);
+ if (PyCode_Check(tmp))
+ update_code_filenames((PyCodeObject *)tmp,
+ oldname, newname);
+ }
+}
+
+static void
+update_compiled_module(PyCodeObject *co, PyObject *newname)
+{
+ PyObject *oldname;
+
+ if (PyUnicode_Compare(co->co_filename, newname) == 0)
+ return;
+
+ oldname = co->co_filename;
+ Py_INCREF(oldname);
+ update_code_filenames(co, oldname, newname);
+ Py_DECREF(oldname);
+}
+
+/*[clinic input]
+_imp._fix_co_filename
+
+ code: object(type="PyCodeObject *", subclass_of="&PyCode_Type")
+ Code object to change.
+
+ path: unicode
+ File path to use.
+ /
+
+Changes code.co_filename to specify the passed-in file path.
+[clinic start generated code]*/
+
+static PyObject *
+_imp__fix_co_filename_impl(PyObject *module, PyCodeObject *code,
+ PyObject *path)
+/*[clinic end generated code: output=1d002f100235587d input=895ba50e78b82f05]*/
+
+{
+ update_compiled_module(code, path);
+
+ Py_RETURN_NONE;
+}
+
+
+/* Forward */
+static const struct _frozen * find_frozen(PyObject *);
+
+
+/* Helper to test for built-in module */
+
+static int
+is_builtin(PyObject *name)
+{
+ int i;
+ for (i = 0; PyImport_Inittab[i].name != NULL; i++) {
+ if (_PyUnicode_EqualToASCIIString(name, PyImport_Inittab[i].name)) {
+ if (PyImport_Inittab[i].initfunc == NULL)
+ return -1;
+ else
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+/* Return a finder object for a sys.path/pkg.__path__ item 'p',
+ possibly by fetching it from the path_importer_cache dict. If it
+ wasn't yet cached, traverse path_hooks until a hook is found
+ that can handle the path item. Return None if no hook could;
+ this tells our caller that the path based finder could not find
+ a finder for this path item. Cache the result in
+ path_importer_cache.
+ Returns a borrowed reference. */
+
+static PyObject *
+get_path_importer(PyThreadState *tstate, PyObject *path_importer_cache,
+ PyObject *path_hooks, PyObject *p)
+{
+ PyObject *importer;
+ Py_ssize_t j, nhooks;
+
+ /* These conditions are the caller's responsibility: */
+ assert(PyList_Check(path_hooks));
+ assert(PyDict_Check(path_importer_cache));
+
+ nhooks = PyList_Size(path_hooks);
+ if (nhooks < 0)
+ return NULL; /* Shouldn't happen */
+
+ importer = PyDict_GetItemWithError(path_importer_cache, p);
+ if (importer != NULL || _PyErr_Occurred(tstate))
+ return importer;
+
+ /* set path_importer_cache[p] to None to avoid recursion */
+ if (PyDict_SetItem(path_importer_cache, p, Py_None) != 0)
+ return NULL;
+
+ for (j = 0; j < nhooks; j++) {
+ PyObject *hook = PyList_GetItem(path_hooks, j);
+ if (hook == NULL)
+ return NULL;
+ importer = PyObject_CallOneArg(hook, p);
+ if (importer != NULL)
+ break;
+
+ if (!_PyErr_ExceptionMatches(tstate, PyExc_ImportError)) {
+ return NULL;
+ }
+ _PyErr_Clear(tstate);
+ }
+ if (importer == NULL) {
+ return Py_None;
+ }
+ if (importer != NULL) {
+ int err = PyDict_SetItem(path_importer_cache, p, importer);
+ Py_DECREF(importer);
+ if (err != 0)
+ return NULL;
+ }
+ return importer;
+}
+
+PyObject *
+PyImport_GetImporter(PyObject *path)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyObject *importer=NULL, *path_importer_cache=NULL, *path_hooks=NULL;
+
+ path_importer_cache = PySys_GetObject("path_importer_cache");
+ path_hooks = PySys_GetObject("path_hooks");
+ if (path_importer_cache != NULL && path_hooks != NULL) {
+ importer = get_path_importer(tstate, path_importer_cache,
+ path_hooks, path);
+ }
+ Py_XINCREF(importer); /* get_path_importer returns a borrowed reference */
+ return importer;
+}
+
+/*[clinic input]
+_imp.create_builtin
+
+ spec: object
+ /
+
+Create an extension module.
+[clinic start generated code]*/
+
+static PyObject *
+_imp_create_builtin(PyObject *module, PyObject *spec)
+/*[clinic end generated code: output=ace7ff22271e6f39 input=37f966f890384e47]*/
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ struct _inittab *p;
+ PyObject *name;
+ const char *namestr;
+ PyObject *mod;
+
+ name = PyObject_GetAttrString(spec, "name");
+ if (name == NULL) {
+ return NULL;
+ }
+
+ mod = _PyImport_FindExtensionObject(name, name);
+ if (mod || _PyErr_Occurred(tstate)) {
+ Py_DECREF(name);
+ Py_XINCREF(mod);
+ return mod;
+ }
+
+ namestr = PyUnicode_AsUTF8(name);
+ if (namestr == NULL) {
+ Py_DECREF(name);
+ return NULL;
+ }
+
+ PyObject *modules = tstate->interp->modules;
+ for (p = PyImport_Inittab; p->name != NULL; p++) {
+ PyModuleDef *def;
+ if (_PyUnicode_EqualToASCIIString(name, p->name)) {
+ if (p->initfunc == NULL) {
+ /* Cannot re-init internal module ("sys" or "builtins") */
+ mod = PyImport_AddModule(namestr);
+ Py_DECREF(name);
+ return mod;
+ }
+ mod = (*p->initfunc)();
+ if (mod == NULL) {
+ Py_DECREF(name);
+ return NULL;
+ }
+ if (PyObject_TypeCheck(mod, &PyModuleDef_Type)) {
+ Py_DECREF(name);
+ return PyModule_FromDefAndSpec((PyModuleDef*)mod, spec);
+ } else {
+ /* Remember pointer to module init function. */
+ def = PyModule_GetDef(mod);
+ if (def == NULL) {
+ Py_DECREF(name);
+ return NULL;
+ }
+ def->m_base.m_init = p->initfunc;
+ if (_PyImport_FixupExtensionObject(mod, name, name,
+ modules) < 0) {
+ Py_DECREF(name);
+ return NULL;
+ }
+ Py_DECREF(name);
+ return mod;
+ }
+ }
+ }
+ Py_DECREF(name);
+ Py_RETURN_NONE;
+}
+
+
+/* Frozen modules */
+
+static const struct _frozen *
+find_frozen(PyObject *name)
+{
+ const struct _frozen *p;
+
+ if (name == NULL)
+ return NULL;
+
+ for (p = PyImport_FrozenModules; ; p++) {
+ if (p->name == NULL)
+ return NULL;
+ if (_PyUnicode_EqualToASCIIString(name, p->name))
+ break;
+ }
+ return p;
+}
+
+static PyObject *
+get_frozen_object(PyObject *name)
+{
+ const struct _frozen *p = find_frozen(name);
+ int size;
+
+ if (p == NULL) {
+ PyErr_Format(PyExc_ImportError,
+ "No such frozen object named %R",
+ name);
+ return NULL;
+ }
+ if (p->code == NULL) {
+ PyErr_Format(PyExc_ImportError,
+ "Excluded frozen object named %R",
+ name);
+ return NULL;
+ }
+ size = p->size;
+ if (size < 0)
+ size = -size;
+ return PyMarshal_ReadObjectFromString((const char *)p->code, size);
+}
+
+static PyObject *
+is_frozen_package(PyObject *name)
+{
+ const struct _frozen *p = find_frozen(name);
+ int size;
+
+ if (p == NULL) {
+ PyErr_Format(PyExc_ImportError,
+ "No such frozen object named %R",
+ name);
+ return NULL;
+ }
+
+ size = p->size;
+
+ if (size < 0)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+}
+
+
+/* Initialize a frozen module.
+ Return 1 for success, 0 if the module is not found, and -1 with
+ an exception set if the initialization failed.
+ This function is also used from frozenmain.c */
+
+int
+PyImport_ImportFrozenModuleObject(PyObject *name)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ const struct _frozen *p;
+ PyObject *co, *m, *d;
+ int ispackage;
+ int size;
+
+ p = find_frozen(name);
+
+ if (p == NULL)
+ return 0;
+ if (p->code == NULL) {
+ _PyErr_Format(tstate, PyExc_ImportError,
+ "Excluded frozen object named %R",
+ name);
+ return -1;
+ }
+ size = p->size;
+ ispackage = (size < 0);
+ if (ispackage)
+ size = -size;
+ co = PyMarshal_ReadObjectFromString((const char *)p->code, size);
+ if (co == NULL)
+ return -1;
+ if (!PyCode_Check(co)) {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "frozen object %R is not a code object",
+ name);
+ goto err_return;
+ }
+ if (ispackage) {
+ /* Set __path__ to the empty list */
+ PyObject *l;
+ int err;
+ m = import_add_module(tstate, name);
+ if (m == NULL)
+ goto err_return;
+ d = PyModule_GetDict(m);
+ l = PyList_New(0);
+ if (l == NULL) {
+ goto err_return;
+ }
+ err = PyDict_SetItemString(d, "__path__", l);
+ Py_DECREF(l);
+ if (err != 0)
+ goto err_return;
+ }
+ d = module_dict_for_exec(tstate, name);
+ if (d == NULL) {
+ goto err_return;
+ }
+ m = exec_code_in_module(tstate, name, d, co);
+ if (m == NULL) {
+ goto err_return;
+ }
+ Py_DECREF(co);
+ Py_DECREF(m);
+ return 1;
+
+err_return:
+ Py_DECREF(co);
+ return -1;
+}
+
+int
+PyImport_ImportFrozenModule(const char *name)
+{
+ PyObject *nameobj;
+ int ret;
+ nameobj = PyUnicode_InternFromString(name);
+ if (nameobj == NULL)
+ return -1;
+ ret = PyImport_ImportFrozenModuleObject(nameobj);
+ Py_DECREF(nameobj);
+ return ret;
+}
+
+
+/* Import a module, either built-in, frozen, or external, and return
+ its module object WITH INCREMENTED REFERENCE COUNT */
+
+PyObject *
+PyImport_ImportModule(const char *name)
+{
+ PyObject *pname;
+ PyObject *result;
+
+ pname = PyUnicode_FromString(name);
+ if (pname == NULL)
+ return NULL;
+ result = PyImport_Import(pname);
+ Py_DECREF(pname);
+ return result;
+}
+
+
+/* Import a module without blocking
+ *
+ * At first it tries to fetch the module from sys.modules. If the module was
+ * never loaded before it loads it with PyImport_ImportModule() unless another
+ * thread holds the import lock. In the latter case the function raises an
+ * ImportError instead of blocking.
+ *
+ * Returns the module object with incremented ref count.
+ */
+PyObject *
+PyImport_ImportModuleNoBlock(const char *name)
+{
+ return PyImport_ImportModule(name);
+}
+
+
+/* Remove importlib frames from the traceback,
+ * except in Verbose mode. */
+static void
+remove_importlib_frames(PyThreadState *tstate)
+{
+ const char *importlib_filename = "<frozen importlib._bootstrap>";
+ const char *external_filename = "<frozen importlib._bootstrap_external>";
+ const char *importer_filename = "library/python/runtime_py3/importer.pxi";
+ const char *remove_frames = "_call_with_frames_removed";
+ int always_trim = 0;
+ int in_importlib = 0;
+ PyObject *exception, *value, *base_tb, *tb;
+ PyObject **prev_link, **outer_link = NULL;
+
+ /* Synopsis: if it's an ImportError, we trim all importlib chunks
+ from the traceback. We always trim chunks
+ which end with a call to "_call_with_frames_removed". */
+
+ _PyErr_Fetch(tstate, &exception, &value, &base_tb);
+ if (!exception || _PyInterpreterState_GetConfig(tstate->interp)->verbose) {
+ goto done;
+ }
+
+ if (PyType_IsSubtype((PyTypeObject *) exception,
+ (PyTypeObject *) PyExc_ImportError))
+ always_trim = 1;
+
+ prev_link = &base_tb;
+ tb = base_tb;
+ while (tb != NULL) {
+ PyTracebackObject *traceback = (PyTracebackObject *)tb;
+ PyObject *next = (PyObject *) traceback->tb_next;
+ PyFrameObject *frame = traceback->tb_frame;
+ PyCodeObject *code = PyFrame_GetCode(frame);
+ int now_in_importlib;
+
+ assert(PyTraceBack_Check(tb));
+ now_in_importlib = _PyUnicode_EqualToASCIIString(code->co_filename, importlib_filename) ||
+ _PyUnicode_EqualToASCIIString(code->co_filename, external_filename) ||
+ _PyUnicode_EqualToASCIIString(code->co_filename, importer_filename);
+ if (now_in_importlib && !in_importlib) {
+ /* This is the link to this chunk of importlib tracebacks */
+ outer_link = prev_link;
+ }
+ in_importlib = now_in_importlib;
+
+ if (in_importlib &&
+ (always_trim ||
+ _PyUnicode_EqualToASCIIString(code->co_name, remove_frames))) {
+ Py_XINCREF(next);
+ Py_XSETREF(*outer_link, next);
+ prev_link = outer_link;
+ }
+ else {
+ prev_link = (PyObject **) &traceback->tb_next;
+ }
+ Py_DECREF(code);
+ tb = next;
+ }
+done:
+ _PyErr_Restore(tstate, exception, value, base_tb);
+}
+
+
+static PyObject *
+resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level)
+{
+ _Py_IDENTIFIER(__package__);
+ _Py_IDENTIFIER(__name__);
+ _Py_IDENTIFIER(parent);
+ PyObject *abs_name;
+ PyObject *package = NULL;
+ PyObject *spec;
+ Py_ssize_t last_dot;
+ PyObject *base;
+ int level_up;
+
+ if (globals == NULL) {
+ _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");
+ goto error;
+ }
+ package = _PyDict_GetItemIdWithError(globals, &PyId___package__);
+ if (package == Py_None) {
+ package = NULL;
+ }
+ else if (package == NULL && _PyErr_Occurred(tstate)) {
+ goto error;
+ }
+ spec = _PyDict_GetItemIdWithError(globals, &PyId___spec__);
+ if (spec == NULL && _PyErr_Occurred(tstate)) {
+ goto error;
+ }
+
+ if (package != NULL) {
+ Py_INCREF(package);
+ if (!PyUnicode_Check(package)) {
+ _PyErr_SetString(tstate, PyExc_TypeError,
+ "package must be a string");
+ goto error;
+ }
+ else if (spec != NULL && spec != Py_None) {
+ int equal;
+ PyObject *parent = _PyObject_GetAttrId(spec, &PyId_parent);
+ if (parent == NULL) {
+ goto error;
+ }
+
+ equal = PyObject_RichCompareBool(package, parent, Py_EQ);
+ Py_DECREF(parent);
+ if (equal < 0) {
+ goto error;
+ }
+ else if (equal == 0) {
+ if (PyErr_WarnEx(PyExc_ImportWarning,
+ "__package__ != __spec__.parent", 1) < 0) {
+ goto error;
+ }
+ }
+ }
+ }
+ else if (spec != NULL && spec != Py_None) {
+ package = _PyObject_GetAttrId(spec, &PyId_parent);
+ if (package == NULL) {
+ goto error;
+ }
+ else if (!PyUnicode_Check(package)) {
+ _PyErr_SetString(tstate, PyExc_TypeError,
+ "__spec__.parent must be a string");
+ goto error;
+ }
+ }
+ else {
+ if (PyErr_WarnEx(PyExc_ImportWarning,
+ "can't resolve package from __spec__ or __package__, "
+ "falling back on __name__ and __path__", 1) < 0) {
+ goto error;
+ }
+
+ package = _PyDict_GetItemIdWithError(globals, &PyId___name__);
+ if (package == NULL) {
+ if (!_PyErr_Occurred(tstate)) {
+ _PyErr_SetString(tstate, PyExc_KeyError,
+ "'__name__' not in globals");
+ }
+ goto error;
+ }
+
+ Py_INCREF(package);
+ if (!PyUnicode_Check(package)) {
+ _PyErr_SetString(tstate, PyExc_TypeError,
+ "__name__ must be a string");
+ goto error;
+ }
+
+ if (_PyDict_GetItemIdWithError(globals, &PyId___path__) == NULL) {
+ Py_ssize_t dot;
+
+ if (_PyErr_Occurred(tstate) || PyUnicode_READY(package) < 0) {
+ goto error;
+ }
+
+ dot = PyUnicode_FindChar(package, '.',
+ 0, PyUnicode_GET_LENGTH(package), -1);
+ if (dot == -2) {
+ goto error;
+ }
+ else if (dot == -1) {
+ goto no_parent_error;
+ }
+ PyObject *substr = PyUnicode_Substring(package, 0, dot);
+ if (substr == NULL) {
+ goto error;
+ }
+ Py_SETREF(package, substr);
+ }
+ }
+
+ last_dot = PyUnicode_GET_LENGTH(package);
+ if (last_dot == 0) {
+ goto no_parent_error;
+ }
+
+ for (level_up = 1; level_up < level; level_up += 1) {
+ last_dot = PyUnicode_FindChar(package, '.', 0, last_dot, -1);
+ if (last_dot == -2) {
+ goto error;
+ }
+ else if (last_dot == -1) {
+ _PyErr_SetString(tstate, PyExc_ImportError,
+ "attempted relative import beyond top-level "
+ "package");
+ goto error;
+ }
+ }
+
+ base = PyUnicode_Substring(package, 0, last_dot);
+ Py_DECREF(package);
+ if (base == NULL || PyUnicode_GET_LENGTH(name) == 0) {
+ return base;
+ }
+
+ abs_name = PyUnicode_FromFormat("%U.%U", base, name);
+ Py_DECREF(base);
+ return abs_name;
+
+ no_parent_error:
+ _PyErr_SetString(tstate, PyExc_ImportError,
+ "attempted relative import "
+ "with no known parent package");
+
+ error:
+ Py_XDECREF(package);
+ return NULL;
+}
+
+static PyObject *
+import_find_and_load(PyThreadState *tstate, PyObject *abs_name)
+{
+ _Py_IDENTIFIER(_find_and_load);
+ PyObject *mod = NULL;
+ PyInterpreterState *interp = tstate->interp;
+ int import_time = _PyInterpreterState_GetConfig(interp)->import_time;
+ static int import_level;
+ static _PyTime_t accumulated;
+
+ _PyTime_t t1 = 0, accumulated_copy = accumulated;
+
+ PyObject *sys_path = PySys_GetObject("path");
+ PyObject *sys_meta_path = PySys_GetObject("meta_path");
+ PyObject *sys_path_hooks = PySys_GetObject("path_hooks");
+ if (_PySys_Audit(tstate, "import", "OOOOO",
+ abs_name, Py_None, sys_path ? sys_path : Py_None,
+ sys_meta_path ? sys_meta_path : Py_None,
+ sys_path_hooks ? sys_path_hooks : Py_None) < 0) {
+ return NULL;
+ }
+
+
+ /* XOptions is initialized after first some imports.
+ * So we can't have negative cache before completed initialization.
+ * Anyway, importlib._find_and_load is much slower than
+ * _PyDict_GetItemIdWithError().
+ */
+ if (import_time) {
+ static int header = 1;
+ if (header) {
+ fputs("import time: self [us] | cumulative | imported package\n",
+ stderr);
+ header = 0;
+ }
+
+ import_level++;
+ t1 = _PyTime_GetPerfCounter();
+ accumulated = 0;
+ }
+
+ if (PyDTrace_IMPORT_FIND_LOAD_START_ENABLED())
+ PyDTrace_IMPORT_FIND_LOAD_START(PyUnicode_AsUTF8(abs_name));
+
+ mod = _PyObject_CallMethodIdObjArgs(interp->importlib,
+ &PyId__find_and_load, abs_name,
+ interp->import_func, NULL);
+
+ if (PyDTrace_IMPORT_FIND_LOAD_DONE_ENABLED())
+ PyDTrace_IMPORT_FIND_LOAD_DONE(PyUnicode_AsUTF8(abs_name),
+ mod != NULL);
+
+ if (import_time) {
+ _PyTime_t cum = _PyTime_GetPerfCounter() - t1;
+
+ import_level--;
+ fprintf(stderr, "import time: %9ld | %10ld | %*s%s\n",
+ (long)_PyTime_AsMicroseconds(cum - accumulated, _PyTime_ROUND_CEILING),
+ (long)_PyTime_AsMicroseconds(cum, _PyTime_ROUND_CEILING),
+ import_level*2, "", PyUnicode_AsUTF8(abs_name));
+
+ accumulated = accumulated_copy + cum;
+ }
+
+ return mod;
+}
+
+PyObject *
+PyImport_GetModule(PyObject *name)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyObject *mod;
+
+ mod = import_get_module(tstate, name);
+ if (mod != NULL && mod != Py_None) {
+ if (import_ensure_initialized(tstate, mod, name) < 0) {
+ Py_DECREF(mod);
+ remove_importlib_frames(tstate);
+ return NULL;
+ }
+ }
+ return mod;
+}
+
+PyObject *
+PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
+ PyObject *locals, PyObject *fromlist,
+ int level)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ _Py_IDENTIFIER(_handle_fromlist);
+ PyObject *abs_name = NULL;
+ PyObject *final_mod = NULL;
+ PyObject *mod = NULL;
+ PyObject *package = NULL;
+ PyInterpreterState *interp = tstate->interp;
+ int has_from;
+
+ if (name == NULL) {
+ _PyErr_SetString(tstate, PyExc_ValueError, "Empty module name");
+ goto error;
+ }
+
+ /* The below code is importlib.__import__() & _gcd_import(), ported to C
+ for added performance. */
+
+ if (!PyUnicode_Check(name)) {
+ _PyErr_SetString(tstate, PyExc_TypeError,
+ "module name must be a string");
+ goto error;
+ }
+ if (PyUnicode_READY(name) < 0) {
+ goto error;
+ }
+ if (level < 0) {
+ _PyErr_SetString(tstate, PyExc_ValueError, "level must be >= 0");
+ 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 = name;
+ Py_INCREF(abs_name);
+ }
+
+ mod = import_get_module(tstate, abs_name);
+ if (mod == NULL && _PyErr_Occurred(tstate)) {
+ goto error;
+ }
+
+ if (mod != NULL && mod != Py_None) {
+ if (import_ensure_initialized(tstate, mod, abs_name) < 0) {
+ goto error;
+ }
+ }
+ else {
+ Py_XDECREF(mod);
+ mod = import_find_and_load(tstate, abs_name);
+ if (mod == NULL) {
+ goto error;
+ }
+ }
+
+ has_from = 0;
+ if (fromlist != NULL && fromlist != Py_None) {
+ has_from = PyObject_IsTrue(fromlist);
+ if (has_from < 0)
+ goto error;
+ }
+ if (!has_from) {
+ Py_ssize_t len = PyUnicode_GET_LENGTH(name);
+ if (level == 0 || len > 0) {
+ Py_ssize_t dot;
+
+ dot = PyUnicode_FindChar(name, '.', 0, len, 1);
+ if (dot == -2) {
+ goto error;
+ }
+
+ if (dot == -1) {
+ /* No dot in module name, simple exit */
+ final_mod = mod;
+ Py_INCREF(mod);
+ goto error;
+ }
+
+ if (level == 0) {
+ PyObject *front = PyUnicode_Substring(name, 0, dot);
+ if (front == NULL) {
+ goto error;
+ }
+
+ final_mod = PyImport_ImportModuleLevelObject(front, NULL, NULL, NULL, 0);
+ Py_DECREF(front);
+ }
+ else {
+ Py_ssize_t cut_off = len - dot;
+ Py_ssize_t abs_name_len = PyUnicode_GET_LENGTH(abs_name);
+ PyObject *to_return = PyUnicode_Substring(abs_name, 0,
+ abs_name_len - cut_off);
+ if (to_return == NULL) {
+ goto error;
+ }
+
+ final_mod = import_get_module(tstate, to_return);
+ Py_DECREF(to_return);
+ if (final_mod == NULL) {
+ if (!_PyErr_Occurred(tstate)) {
+ _PyErr_Format(tstate, PyExc_KeyError,
+ "%R not in sys.modules as expected",
+ to_return);
+ }
+ goto error;
+ }
+ }
+ }
+ else {
+ final_mod = mod;
+ Py_INCREF(mod);
+ }
+ }
+ else {
+ PyObject *path;
+ if (_PyObject_LookupAttrId(mod, &PyId___path__, &path) < 0) {
+ goto error;
+ }
+ if (path) {
+ Py_DECREF(path);
+ final_mod = _PyObject_CallMethodIdObjArgs(
+ interp->importlib, &PyId__handle_fromlist,
+ mod, fromlist, interp->import_func, NULL);
+ }
+ else {
+ final_mod = mod;
+ Py_INCREF(mod);
+ }
+ }
+
+ error:
+ Py_XDECREF(abs_name);
+ Py_XDECREF(mod);
+ Py_XDECREF(package);
+ if (final_mod == NULL) {
+ remove_importlib_frames(tstate);
+ }
+ return final_mod;
+}
+
+PyObject *
+PyImport_ImportModuleLevel(const char *name, PyObject *globals, PyObject *locals,
+ PyObject *fromlist, int level)
+{
+ PyObject *nameobj, *mod;
+ nameobj = PyUnicode_FromString(name);
+ if (nameobj == NULL)
+ return NULL;
+ mod = PyImport_ImportModuleLevelObject(nameobj, globals, locals,
+ fromlist, level);
+ Py_DECREF(nameobj);
+ return mod;
+}
+
+
+/* Re-import a module of any kind and return its module object, WITH
+ INCREMENTED REFERENCE COUNT */
+
+PyObject *
+PyImport_ReloadModule(PyObject *m)
+{
+ _Py_IDENTIFIER(importlib);
+ _Py_IDENTIFIER(reload);
+ PyObject *reloaded_module = NULL;
+ PyObject *importlib = _PyImport_GetModuleId(&PyId_importlib);
+ if (importlib == NULL) {
+ if (PyErr_Occurred()) {
+ return NULL;
+ }
+
+ importlib = PyImport_ImportModule("importlib");
+ if (importlib == NULL) {
+ return NULL;
+ }
+ }
+
+ reloaded_module = _PyObject_CallMethodIdOneArg(importlib, &PyId_reload, m);
+ Py_DECREF(importlib);
+ return reloaded_module;
+}
+
+
+/* Higher-level import emulator which emulates the "import" statement
+ more accurately -- it invokes the __import__() function from the
+ builtins of the current globals. This means that the import is
+ done using whatever import hooks are installed in the current
+ environment.
+ A dummy list ["__doc__"] is passed as the 4th argument so that
+ e.g. PyImport_Import(PyUnicode_FromString("win32com.client.gencache"))
+ will return <module "gencache"> instead of <module "win32com">. */
+
+PyObject *
+PyImport_Import(PyObject *module_name)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ static PyObject *silly_list = NULL;
+ static PyObject *builtins_str = NULL;
+ static PyObject *import_str = NULL;
+ PyObject *globals = NULL;
+ PyObject *import = NULL;
+ PyObject *builtins = NULL;
+ PyObject *r = NULL;
+
+ /* Initialize constant string objects */
+ if (silly_list == NULL) {
+ import_str = PyUnicode_InternFromString("__import__");
+ if (import_str == NULL)
+ return NULL;
+ builtins_str = PyUnicode_InternFromString("__builtins__");
+ if (builtins_str == NULL)
+ return NULL;
+ silly_list = PyList_New(0);
+ if (silly_list == NULL)
+ return NULL;
+ }
+
+ /* Get the builtins from current globals */
+ globals = PyEval_GetGlobals();
+ if (globals != NULL) {
+ Py_INCREF(globals);
+ builtins = PyObject_GetItem(globals, builtins_str);
+ if (builtins == NULL)
+ goto err;
+ }
+ else {
+ /* No globals -- use standard builtins, and fake globals */
+ builtins = PyImport_ImportModuleLevel("builtins",
+ NULL, NULL, NULL, 0);
+ if (builtins == NULL)
+ return NULL;
+ globals = Py_BuildValue("{OO}", builtins_str, builtins);
+ if (globals == NULL)
+ goto err;
+ }
+
+ /* Get the __import__ function from the builtins */
+ if (PyDict_Check(builtins)) {
+ import = PyObject_GetItem(builtins, import_str);
+ if (import == NULL) {
+ _PyErr_SetObject(tstate, PyExc_KeyError, import_str);
+ }
+ }
+ else
+ import = PyObject_GetAttr(builtins, import_str);
+ if (import == NULL)
+ goto err;
+
+ /* Call the __import__ function with the proper argument list
+ Always use absolute import here.
+ Calling for side-effect of import. */
+ r = PyObject_CallFunction(import, "OOOOi", module_name, globals,
+ globals, silly_list, 0, NULL);
+ if (r == NULL)
+ goto err;
+ Py_DECREF(r);
+
+ r = import_get_module(tstate, module_name);
+ if (r == NULL && !_PyErr_Occurred(tstate)) {
+ _PyErr_SetObject(tstate, PyExc_KeyError, module_name);
+ }
+
+ err:
+ Py_XDECREF(globals);
+ Py_XDECREF(builtins);
+ Py_XDECREF(import);
+
+ return r;
+}
+
+/*[clinic input]
+_imp.extension_suffixes
+
+Returns the list of file suffixes used to identify extension modules.
+[clinic start generated code]*/
+
+static PyObject *
+_imp_extension_suffixes_impl(PyObject *module)
+/*[clinic end generated code: output=0bf346e25a8f0cd3 input=ecdeeecfcb6f839e]*/
+{
+ PyObject *list;
+
+ list = PyList_New(0);
+ if (list == NULL)
+ return NULL;
+#ifdef HAVE_DYNAMIC_LOADING
+ const char *suffix;
+ unsigned int index = 0;
+
+ while ((suffix = _PyImport_DynLoadFiletab[index])) {
+ PyObject *item = PyUnicode_FromString(suffix);
+ if (item == NULL) {
+ Py_DECREF(list);
+ return NULL;
+ }
+ if (PyList_Append(list, item) < 0) {
+ Py_DECREF(list);
+ Py_DECREF(item);
+ return NULL;
+ }
+ Py_DECREF(item);
+ index += 1;
+ }
+#endif
+ return list;
+}
+
+/*[clinic input]
+_imp.init_frozen
+
+ name: unicode
+ /
+
+Initializes a frozen module.
+[clinic start generated code]*/
+
+static PyObject *
+_imp_init_frozen_impl(PyObject *module, PyObject *name)
+/*[clinic end generated code: output=fc0511ed869fd69c input=13019adfc04f3fb3]*/
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ int ret;
+ PyObject *m;
+
+ ret = PyImport_ImportFrozenModuleObject(name);
+ if (ret < 0)
+ return NULL;
+ if (ret == 0) {
+ Py_RETURN_NONE;
+ }
+ m = import_add_module(tstate, name);
+ Py_XINCREF(m);
+ return m;
+}
+
+/*[clinic input]
+_imp.get_frozen_object
+
+ name: unicode
+ /
+
+Create a code object for a frozen module.
+[clinic start generated code]*/
+
+static PyObject *
+_imp_get_frozen_object_impl(PyObject *module, PyObject *name)
+/*[clinic end generated code: output=2568cc5b7aa0da63 input=ed689bc05358fdbd]*/
+{
+ return get_frozen_object(name);
+}
+
+/*[clinic input]
+_imp.is_frozen_package
+
+ name: unicode
+ /
+
+Returns True if the module name is of a frozen package.
+[clinic start generated code]*/
+
+static PyObject *
+_imp_is_frozen_package_impl(PyObject *module, PyObject *name)
+/*[clinic end generated code: output=e70cbdb45784a1c9 input=81b6cdecd080fbb8]*/
+{
+ return is_frozen_package(name);
+}
+
+/*[clinic input]
+_imp.is_builtin
+
+ name: unicode
+ /
+
+Returns True if the module name corresponds to a built-in module.
+[clinic start generated code]*/
+
+static PyObject *
+_imp_is_builtin_impl(PyObject *module, PyObject *name)
+/*[clinic end generated code: output=3bfd1162e2d3be82 input=86befdac021dd1c7]*/
+{
+ return PyLong_FromLong(is_builtin(name));
+}
+
+/*[clinic input]
+_imp.is_frozen
+
+ name: unicode
+ /
+
+Returns True if the module name corresponds to a frozen module.
+[clinic start generated code]*/
+
+static PyObject *
+_imp_is_frozen_impl(PyObject *module, PyObject *name)
+/*[clinic end generated code: output=01f408f5ec0f2577 input=7301dbca1897d66b]*/
+{
+ const struct _frozen *p;
+
+ p = find_frozen(name);
+ return PyBool_FromLong((long) (p == NULL ? 0 : p->size));
+}
+
+/* Common implementation for _imp.exec_dynamic and _imp.exec_builtin */
+static int
+exec_builtin_or_dynamic(PyObject *mod) {
+ PyModuleDef *def;
+ void *state;
+
+ if (!PyModule_Check(mod)) {
+ return 0;
+ }
+
+ def = PyModule_GetDef(mod);
+ if (def == NULL) {
+ return 0;
+ }
+
+ state = PyModule_GetState(mod);
+ if (state) {
+ /* Already initialized; skip reload */
+ return 0;
+ }
+
+ return PyModule_ExecDef(mod, def);
+}
+
+#ifdef HAVE_DYNAMIC_LOADING
+
+/*[clinic input]
+_imp.create_dynamic
+
+ spec: object
+ file: object = NULL
+ /
+
+Create an extension module.
+[clinic start generated code]*/
+
+static PyObject *
+_imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file)
+/*[clinic end generated code: output=83249b827a4fde77 input=c31b954f4cf4e09d]*/
+{
+ PyObject *mod, *name, *path;
+ FILE *fp;
+
+ name = PyObject_GetAttrString(spec, "name");
+ if (name == NULL) {
+ return NULL;
+ }
+
+ path = PyObject_GetAttrString(spec, "origin");
+ if (path == NULL) {
+ Py_DECREF(name);
+ return NULL;
+ }
+
+ mod = _PyImport_FindExtensionObject(name, path);
+ if (mod != NULL || PyErr_Occurred()) {
+ Py_DECREF(name);
+ Py_DECREF(path);
+ Py_XINCREF(mod);
+ return mod;
+ }
+
+ if (file != NULL) {
+ fp = _Py_fopen_obj(path, "r");
+ if (fp == NULL) {
+ Py_DECREF(name);
+ Py_DECREF(path);
+ return NULL;
+ }
+ }
+ else
+ fp = NULL;
+
+ mod = _PyImport_LoadDynamicModuleWithSpec(spec, fp);
+
+ Py_DECREF(name);
+ Py_DECREF(path);
+ if (fp)
+ fclose(fp);
+ return mod;
+}
+
+/*[clinic input]
+_imp.exec_dynamic -> int
+
+ mod: object
+ /
+
+Initialize an extension module.
+[clinic start generated code]*/
+
+static int
+_imp_exec_dynamic_impl(PyObject *module, PyObject *mod)
+/*[clinic end generated code: output=f5720ac7b465877d input=9fdbfcb250280d3a]*/
+{
+ return exec_builtin_or_dynamic(mod);
+}
+
+
+#endif /* HAVE_DYNAMIC_LOADING */
+
+/*[clinic input]
+_imp.exec_builtin -> int
+
+ mod: object
+ /
+
+Initialize a built-in module.
+[clinic start generated code]*/
+
+static int
+_imp_exec_builtin_impl(PyObject *module, PyObject *mod)
+/*[clinic end generated code: output=0262447b240c038e input=7beed5a2f12a60ca]*/
+{
+ return exec_builtin_or_dynamic(mod);
+}
+
+/*[clinic input]
+_imp.source_hash
+
+ key: long
+ source: Py_buffer
+[clinic start generated code]*/
+
+static PyObject *
+_imp_source_hash_impl(PyObject *module, long key, Py_buffer *source)
+/*[clinic end generated code: output=edb292448cf399ea input=9aaad1e590089789]*/
+{
+ union {
+ uint64_t x;
+ char data[sizeof(uint64_t)];
+ } hash;
+ hash.x = _Py_KeyedHash((uint64_t)key, source->buf, source->len);
+#if !PY_LITTLE_ENDIAN
+ // Force to little-endian. There really ought to be a succinct standard way
+ // to do this.
+ for (size_t i = 0; i < sizeof(hash.data)/2; i++) {
+ char tmp = hash.data[i];
+ hash.data[i] = hash.data[sizeof(hash.data) - i - 1];
+ hash.data[sizeof(hash.data) - i - 1] = tmp;
+ }
+#endif
+ return PyBytes_FromStringAndSize(hash.data, sizeof(hash.data));
+}
+
+
+PyDoc_STRVAR(doc_imp,
+"(Extremely) low-level import machinery bits as used by importlib and imp.");
+
+static PyMethodDef imp_methods[] = {
+ _IMP_EXTENSION_SUFFIXES_METHODDEF
+ _IMP_LOCK_HELD_METHODDEF
+ _IMP_ACQUIRE_LOCK_METHODDEF
+ _IMP_RELEASE_LOCK_METHODDEF
+ _IMP_GET_FROZEN_OBJECT_METHODDEF
+ _IMP_IS_FROZEN_PACKAGE_METHODDEF
+ _IMP_CREATE_BUILTIN_METHODDEF
+ _IMP_INIT_FROZEN_METHODDEF
+ _IMP_IS_BUILTIN_METHODDEF
+ _IMP_IS_FROZEN_METHODDEF
+ _IMP_CREATE_DYNAMIC_METHODDEF
+ _IMP_EXEC_DYNAMIC_METHODDEF
+ _IMP_EXEC_BUILTIN_METHODDEF
+ _IMP__FIX_CO_FILENAME_METHODDEF
+ _IMP_SOURCE_HASH_METHODDEF
+ {NULL, NULL} /* sentinel */
+};
+
+
+static struct PyModuleDef impmodule = {
+ PyModuleDef_HEAD_INIT,
+ "_imp",
+ doc_imp,
+ 0,
+ imp_methods,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+PyMODINIT_FUNC
+PyInit__imp(void)
+{
+ PyObject *m, *d;
+
+ m = PyModule_Create(&impmodule);
+ if (m == NULL) {
+ goto failure;
+ }
+ d = PyModule_GetDict(m);
+ if (d == NULL) {
+ goto failure;
+ }
+
+ const wchar_t *mode = _Py_GetConfig()->check_hash_pycs_mode;
+ PyObject *pyc_mode = PyUnicode_FromWideChar(mode, -1);
+ if (pyc_mode == NULL) {
+ goto failure;
+ }
+ if (PyDict_SetItemString(d, "check_hash_based_pycs", pyc_mode) < 0) {
+ Py_DECREF(pyc_mode);
+ goto failure;
+ }
+ Py_DECREF(pyc_mode);
+
+ return m;
+ failure:
+ Py_XDECREF(m);
+ return NULL;
+}
+
+
+/* API for embedding applications that want to add their own entries
+ to the table of built-in modules. This should normally be called
+ *before* Py_Initialize(). When the table resize fails, -1 is
+ returned and the existing table is unchanged.
+
+ After a similar function by Just van Rossum. */
+
+int
+PyImport_ExtendInittab(struct _inittab *newtab)
+{
+ struct _inittab *p;
+ size_t i, n;
+ int res = 0;
+
+ /* Count the number of entries in both tables */
+ for (n = 0; newtab[n].name != NULL; n++)
+ ;
+ if (n == 0)
+ return 0; /* Nothing to do */
+ for (i = 0; PyImport_Inittab[i].name != NULL; i++)
+ ;
+
+ /* Force default raw memory allocator to get a known allocator to be able
+ to release the memory in _PyImport_Fini2() */
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ /* Allocate new memory for the combined table */
+ p = NULL;
+ if (i + n <= SIZE_MAX / sizeof(struct _inittab) - 1) {
+ size_t size = sizeof(struct _inittab) * (i + n + 1);
+ p = PyMem_RawRealloc(inittab_copy, size);
+ }
+ if (p == NULL) {
+ res = -1;
+ goto done;
+ }
+
+ /* Copy the tables into the new memory at the first call
+ to PyImport_ExtendInittab(). */
+ if (inittab_copy != PyImport_Inittab) {
+ memcpy(p, PyImport_Inittab, (i+1) * sizeof(struct _inittab));
+ }
+ memcpy(p + i, newtab, (n + 1) * sizeof(struct _inittab));
+ PyImport_Inittab = inittab_copy = p;
+
+done:
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+ return res;
+}
+
+/* Shorthand to add a single entry given a name and a function */
+
+int
+PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void))
+{
+ struct _inittab newtab[2];
+
+ memset(newtab, '\0', sizeof newtab);
+
+ newtab[0].name = name;
+ newtab[0].initfunc = initfunc;
+
+ return PyImport_ExtendInittab(newtab);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/contrib/tools/python3/src/Python/importdl.c b/contrib/tools/python3/src/Python/importdl.c
new file mode 100644
index 00000000000..134f6680c44
--- /dev/null
+++ b/contrib/tools/python3/src/Python/importdl.c
@@ -0,0 +1,249 @@
+
+/* Support for dynamic loading of extension modules */
+
+#include "Python.h"
+
+/* ./configure sets HAVE_DYNAMIC_LOADING if dynamic loading of modules is
+ supported on this platform. configure will then compile and link in one
+ of the dynload_*.c files, as appropriate. We will call a function in
+ those modules to get a function pointer to the module's init function.
+*/
+#ifdef HAVE_DYNAMIC_LOADING
+
+#include "importdl.h"
+
+#ifdef MS_WINDOWS
+extern dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix,
+ const char *shortname,
+ PyObject *pathname,
+ FILE *fp);
+#else
+extern dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix,
+ const char *shortname,
+ const char *pathname, FILE *fp);
+#endif
+
+static const char * const ascii_only_prefix = "PyInit";
+static const char * const nonascii_prefix = "PyInitU";
+
+/* Get the variable part of a module's export symbol name.
+ * Returns a bytes instance. For non-ASCII-named modules, the name is
+ * encoded as per PEP 489.
+ * The hook_prefix pointer is set to either ascii_only_prefix or
+ * nonascii_prefix, as appropriate.
+ */
+static PyObject *
+get_encoded_name(PyObject *name, const char **hook_prefix) {
+ PyObject *tmp;
+ PyObject *encoded = NULL;
+ PyObject *modname = NULL;
+ Py_ssize_t name_len, lastdot;
+ _Py_IDENTIFIER(replace);
+
+ /* Get the short name (substring after last dot) */
+ name_len = PyUnicode_GetLength(name);
+ if (name_len < 0) {
+ return NULL;
+ }
+ lastdot = PyUnicode_FindChar(name, '.', 0, name_len, -1);
+ if (lastdot < -1) {
+ return NULL;
+ } else if (lastdot >= 0) {
+ tmp = PyUnicode_Substring(name, lastdot + 1, name_len);
+ if (tmp == NULL)
+ return NULL;
+ name = tmp;
+ /* "name" now holds a new reference to the substring */
+ } else {
+ Py_INCREF(name);
+ }
+
+ /* Encode to ASCII or Punycode, as needed */
+ encoded = PyUnicode_AsEncodedString(name, "ascii", NULL);
+ if (encoded != NULL) {
+ *hook_prefix = ascii_only_prefix;
+ } else {
+ if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
+ PyErr_Clear();
+ encoded = PyUnicode_AsEncodedString(name, "punycode", NULL);
+ if (encoded == NULL) {
+ goto error;
+ }
+ *hook_prefix = nonascii_prefix;
+ } else {
+ goto error;
+ }
+ }
+
+ /* Replace '-' by '_' */
+ modname = _PyObject_CallMethodId(encoded, &PyId_replace, "cc", '-', '_');
+ if (modname == NULL)
+ goto error;
+
+ Py_DECREF(name);
+ Py_DECREF(encoded);
+ return modname;
+error:
+ Py_DECREF(name);
+ Py_XDECREF(encoded);
+ return NULL;
+}
+
+PyObject *
+_PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp)
+{
+#ifndef MS_WINDOWS
+ PyObject *pathbytes = NULL;
+#endif
+ PyObject *name_unicode = NULL, *name = NULL, *path = NULL, *m = NULL;
+ const char *name_buf, *hook_prefix;
+ const char *oldcontext;
+ dl_funcptr exportfunc;
+ PyModuleDef *def;
+ PyObject *(*p0)(void);
+
+ name_unicode = PyObject_GetAttrString(spec, "name");
+ if (name_unicode == NULL) {
+ return NULL;
+ }
+ if (!PyUnicode_Check(name_unicode)) {
+ PyErr_SetString(PyExc_TypeError,
+ "spec.name must be a string");
+ goto error;
+ }
+
+ name = get_encoded_name(name_unicode, &hook_prefix);
+ if (name == NULL) {
+ goto error;
+ }
+ name_buf = PyBytes_AS_STRING(name);
+
+ path = PyObject_GetAttrString(spec, "origin");
+ if (path == NULL)
+ goto error;
+
+ if (PySys_Audit("import", "OOOOO", name_unicode, path,
+ Py_None, Py_None, Py_None) < 0) {
+ goto error;
+ }
+
+#ifdef MS_WINDOWS
+ exportfunc = _PyImport_FindSharedFuncptrWindows(hook_prefix, name_buf,
+ path, fp);
+#else
+ pathbytes = PyUnicode_EncodeFSDefault(path);
+ if (pathbytes == NULL)
+ goto error;
+ exportfunc = _PyImport_FindSharedFuncptr(hook_prefix, name_buf,
+ PyBytes_AS_STRING(pathbytes),
+ fp);
+ Py_DECREF(pathbytes);
+#endif
+
+ if (exportfunc == NULL) {
+ if (!PyErr_Occurred()) {
+ PyObject *msg;
+ msg = PyUnicode_FromFormat(
+ "dynamic module does not define "
+ "module export function (%s_%s)",
+ hook_prefix, name_buf);
+ if (msg == NULL)
+ goto error;
+ PyErr_SetImportError(msg, name_unicode, path);
+ Py_DECREF(msg);
+ }
+ goto error;
+ }
+
+ p0 = (PyObject *(*)(void))exportfunc;
+
+ /* Package context is needed for single-phase init */
+ oldcontext = _Py_PackageContext;
+ _Py_PackageContext = PyUnicode_AsUTF8(name_unicode);
+ if (_Py_PackageContext == NULL) {
+ _Py_PackageContext = oldcontext;
+ goto error;
+ }
+ m = p0();
+ _Py_PackageContext = oldcontext;
+
+ if (m == NULL) {
+ if (!PyErr_Occurred()) {
+ PyErr_Format(
+ PyExc_SystemError,
+ "initialization of %s failed without raising an exception",
+ name_buf);
+ }
+ goto error;
+ } else if (PyErr_Occurred()) {
+ PyErr_Clear();
+ PyErr_Format(
+ PyExc_SystemError,
+ "initialization of %s raised unreported exception",
+ name_buf);
+ m = NULL;
+ goto error;
+ }
+ if (Py_IS_TYPE(m, NULL)) {
+ /* This can happen when a PyModuleDef is returned without calling
+ * PyModuleDef_Init on it
+ */
+ PyErr_Format(PyExc_SystemError,
+ "init function of %s returned uninitialized object",
+ name_buf);
+ m = NULL; /* prevent segfault in DECREF */
+ goto error;
+ }
+ if (PyObject_TypeCheck(m, &PyModuleDef_Type)) {
+ Py_DECREF(name_unicode);
+ Py_DECREF(name);
+ Py_DECREF(path);
+ return PyModule_FromDefAndSpec((PyModuleDef*)m, spec);
+ }
+
+ /* Fall back to single-phase init mechanism */
+
+ if (hook_prefix == nonascii_prefix) {
+ /* don't allow legacy init for non-ASCII module names */
+ PyErr_Format(
+ PyExc_SystemError,
+ "initialization of %s did not return PyModuleDef",
+ name_buf);
+ goto error;
+ }
+
+ /* Remember pointer to module init function. */
+ def = PyModule_GetDef(m);
+ if (def == NULL) {
+ PyErr_Format(PyExc_SystemError,
+ "initialization of %s did not return an extension "
+ "module", name_buf);
+ goto error;
+ }
+ def->m_base.m_init = p0;
+
+ /* Remember the filename as the __file__ attribute */
+ if (PyModule_AddObject(m, "__file__", path) < 0)
+ PyErr_Clear(); /* Not important enough to report */
+ else
+ Py_INCREF(path);
+
+ PyObject *modules = PyImport_GetModuleDict();
+ if (_PyImport_FixupExtensionObject(m, name_unicode, path, modules) < 0)
+ goto error;
+
+ Py_DECREF(name_unicode);
+ Py_DECREF(name);
+ Py_DECREF(path);
+
+ return m;
+
+error:
+ Py_DECREF(name_unicode);
+ Py_XDECREF(name);
+ Py_XDECREF(path);
+ Py_XDECREF(m);
+ return NULL;
+}
+
+#endif /* HAVE_DYNAMIC_LOADING */
diff --git a/contrib/tools/python3/src/Python/importdl.h b/contrib/tools/python3/src/Python/importdl.h
new file mode 100644
index 00000000000..9847652b1f1
--- /dev/null
+++ b/contrib/tools/python3/src/Python/importdl.h
@@ -0,0 +1,27 @@
+#ifndef Py_IMPORTDL_H
+#define Py_IMPORTDL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern const char *_PyImport_DynLoadFiletab[];
+
+extern PyObject *_PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *);
+
+/* Max length of module suffix searched for -- accommodates "module.slb" */
+#define MAXSUFFIXSIZE 12
+
+#ifdef MS_WINDOWS
+#include <windows.h>
+typedef FARPROC dl_funcptr;
+#else
+typedef void (*dl_funcptr)(void);
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_IMPORTDL_H */
diff --git a/contrib/tools/python3/src/Python/importlib.h b/contrib/tools/python3/src/Python/importlib.h
new file mode 100644
index 00000000000..1fb877a7534
--- /dev/null
+++ b/contrib/tools/python3/src/Python/importlib.h
@@ -0,0 +1,1812 @@
+/* Auto-generated by Programs/_freeze_importlib.c */
+const unsigned char _Py_M__importlib_bootstrap[] = {
+ 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,4,0,0,0,64,0,0,0,115,194,1,0,0,100,0,
+ 90,0,100,1,97,1,100,2,100,3,132,0,90,2,100,4,
+ 100,5,132,0,90,3,105,0,90,4,105,0,90,5,71,0,
+ 100,6,100,7,132,0,100,7,101,6,131,3,90,7,71,0,
+ 100,8,100,9,132,0,100,9,131,2,90,8,71,0,100,10,
+ 100,11,132,0,100,11,131,2,90,9,71,0,100,12,100,13,
+ 132,0,100,13,131,2,90,10,100,14,100,15,132,0,90,11,
+ 100,16,100,17,132,0,90,12,100,18,100,19,132,0,90,13,
+ 100,20,100,21,156,1,100,22,100,23,132,2,90,14,100,24,
+ 100,25,132,0,90,15,100,26,100,27,132,0,90,16,100,28,
+ 100,29,132,0,90,17,100,30,100,31,132,0,90,18,71,0,
+ 100,32,100,33,132,0,100,33,131,2,90,19,100,1,100,1,
+ 100,34,156,2,100,35,100,36,132,2,90,20,100,94,100,37,
+ 100,38,132,1,90,21,100,39,100,40,156,1,100,41,100,42,
+ 132,2,90,22,100,43,100,44,132,0,90,23,100,45,100,46,
+ 132,0,90,24,100,47,100,48,132,0,90,25,100,49,100,50,
+ 132,0,90,26,100,51,100,52,132,0,90,27,100,53,100,54,
+ 132,0,90,28,71,0,100,55,100,56,132,0,100,56,131,2,
+ 90,29,71,0,100,57,100,58,132,0,100,58,131,2,90,30,
+ 71,0,100,59,100,60,132,0,100,60,131,2,90,31,100,61,
+ 100,62,132,0,90,32,100,63,100,64,132,0,90,33,100,95,
+ 100,65,100,66,132,1,90,34,100,67,100,68,132,0,90,35,
+ 100,69,90,36,101,36,100,70,23,0,90,37,100,71,100,72,
+ 132,0,90,38,101,39,131,0,90,40,100,73,100,74,132,0,
+ 90,41,100,96,100,76,100,77,132,1,90,42,100,39,100,78,
+ 156,1,100,79,100,80,132,2,90,43,100,81,100,82,132,0,
+ 90,44,100,97,100,84,100,85,132,1,90,45,100,86,100,87,
+ 132,0,90,46,100,88,100,89,132,0,90,47,100,90,100,91,
+ 132,0,90,48,100,92,100,93,132,0,90,49,100,1,83,0,
+ 41,98,97,83,1,0,0,67,111,114,101,32,105,109,112,108,
+ 101,109,101,110,116,97,116,105,111,110,32,111,102,32,105,109,
+ 112,111,114,116,46,10,10,84,104,105,115,32,109,111,100,117,
+ 108,101,32,105,115,32,78,79,84,32,109,101,97,110,116,32,
+ 116,111,32,98,101,32,100,105,114,101,99,116,108,121,32,105,
+ 109,112,111,114,116,101,100,33,32,73,116,32,104,97,115,32,
+ 98,101,101,110,32,100,101,115,105,103,110,101,100,32,115,117,
+ 99,104,10,116,104,97,116,32,105,116,32,99,97,110,32,98,
+ 101,32,98,111,111,116,115,116,114,97,112,112,101,100,32,105,
+ 110,116,111,32,80,121,116,104,111,110,32,97,115,32,116,104,
+ 101,32,105,109,112,108,101,109,101,110,116,97,116,105,111,110,
+ 32,111,102,32,105,109,112,111,114,116,46,32,65,115,10,115,
+ 117,99,104,32,105,116,32,114,101,113,117,105,114,101,115,32,
+ 116,104,101,32,105,110,106,101,99,116,105,111,110,32,111,102,
+ 32,115,112,101,99,105,102,105,99,32,109,111,100,117,108,101,
+ 115,32,97,110,100,32,97,116,116,114,105,98,117,116,101,115,
+ 32,105,110,32,111,114,100,101,114,32,116,111,10,119,111,114,
+ 107,46,32,79,110,101,32,115,104,111,117,108,100,32,117,115,
+ 101,32,105,109,112,111,114,116,108,105,98,32,97,115,32,116,
+ 104,101,32,112,117,98,108,105,99,45,102,97,99,105,110,103,
+ 32,118,101,114,115,105,111,110,32,111,102,32,116,104,105,115,
+ 32,109,111,100,117,108,101,46,10,10,78,99,2,0,0,0,
+ 0,0,0,0,0,0,0,0,3,0,0,0,7,0,0,0,
+ 67,0,0,0,115,56,0,0,0,100,1,68,0,93,32,125,
+ 2,116,0,124,1,124,2,131,2,114,4,116,1,124,0,124,
+ 2,116,2,124,1,124,2,131,2,131,3,1,0,113,4,124,
+ 0,106,3,160,4,124,1,106,3,161,1,1,0,100,2,83,
+ 0,41,3,122,47,83,105,109,112,108,101,32,115,117,98,115,
+ 116,105,116,117,116,101,32,102,111,114,32,102,117,110,99,116,
+ 111,111,108,115,46,117,112,100,97,116,101,95,119,114,97,112,
+ 112,101,114,46,41,4,218,10,95,95,109,111,100,117,108,101,
+ 95,95,218,8,95,95,110,97,109,101,95,95,218,12,95,95,
+ 113,117,97,108,110,97,109,101,95,95,218,7,95,95,100,111,
+ 99,95,95,78,41,5,218,7,104,97,115,97,116,116,114,218,
+ 7,115,101,116,97,116,116,114,218,7,103,101,116,97,116,116,
+ 114,218,8,95,95,100,105,99,116,95,95,218,6,117,112,100,
+ 97,116,101,41,3,90,3,110,101,119,90,3,111,108,100,218,
+ 7,114,101,112,108,97,99,101,169,0,114,10,0,0,0,250,
+ 29,60,102,114,111,122,101,110,32,105,109,112,111,114,116,108,
+ 105,98,46,95,98,111,111,116,115,116,114,97,112,62,218,5,
+ 95,119,114,97,112,27,0,0,0,115,8,0,0,0,0,2,
+ 8,1,10,1,20,1,114,12,0,0,0,99,1,0,0,0,
+ 0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,
+ 67,0,0,0,115,12,0,0,0,116,0,116,1,131,1,124,
+ 0,131,1,83,0,169,1,78,41,2,218,4,116,121,112,101,
+ 218,3,115,121,115,169,1,218,4,110,97,109,101,114,10,0,
+ 0,0,114,10,0,0,0,114,11,0,0,0,218,11,95,110,
+ 101,119,95,109,111,100,117,108,101,35,0,0,0,115,2,0,
+ 0,0,0,1,114,18,0,0,0,99,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,1,0,0,0,64,0,
+ 0,0,115,12,0,0,0,101,0,90,1,100,0,90,2,100,
+ 1,83,0,41,2,218,14,95,68,101,97,100,108,111,99,107,
+ 69,114,114,111,114,78,41,3,114,1,0,0,0,114,0,0,
+ 0,0,114,2,0,0,0,114,10,0,0,0,114,10,0,0,
+ 0,114,10,0,0,0,114,11,0,0,0,114,19,0,0,0,
+ 48,0,0,0,115,2,0,0,0,8,1,114,19,0,0,0,
+ 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,2,0,0,0,64,0,0,0,115,56,0,0,0,101,0,
+ 90,1,100,0,90,2,100,1,90,3,100,2,100,3,132,0,
+ 90,4,100,4,100,5,132,0,90,5,100,6,100,7,132,0,
+ 90,6,100,8,100,9,132,0,90,7,100,10,100,11,132,0,
+ 90,8,100,12,83,0,41,13,218,11,95,77,111,100,117,108,
+ 101,76,111,99,107,122,169,65,32,114,101,99,117,114,115,105,
+ 118,101,32,108,111,99,107,32,105,109,112,108,101,109,101,110,
+ 116,97,116,105,111,110,32,119,104,105,99,104,32,105,115,32,
+ 97,98,108,101,32,116,111,32,100,101,116,101,99,116,32,100,
+ 101,97,100,108,111,99,107,115,10,32,32,32,32,40,101,46,
+ 103,46,32,116,104,114,101,97,100,32,49,32,116,114,121,105,
+ 110,103,32,116,111,32,116,97,107,101,32,108,111,99,107,115,
+ 32,65,32,116,104,101,110,32,66,44,32,97,110,100,32,116,
+ 104,114,101,97,100,32,50,32,116,114,121,105,110,103,32,116,
+ 111,10,32,32,32,32,116,97,107,101,32,108,111,99,107,115,
+ 32,66,32,116,104,101,110,32,65,41,46,10,32,32,32,32,
+ 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,
+ 0,2,0,0,0,67,0,0,0,115,48,0,0,0,116,0,
+ 160,1,161,0,124,0,95,2,116,0,160,1,161,0,124,0,
+ 95,3,124,1,124,0,95,4,100,0,124,0,95,5,100,1,
+ 124,0,95,6,100,1,124,0,95,7,100,0,83,0,169,2,
+ 78,233,0,0,0,0,41,8,218,7,95,116,104,114,101,97,
+ 100,90,13,97,108,108,111,99,97,116,101,95,108,111,99,107,
+ 218,4,108,111,99,107,218,6,119,97,107,101,117,112,114,17,
+ 0,0,0,218,5,111,119,110,101,114,218,5,99,111,117,110,
+ 116,218,7,119,97,105,116,101,114,115,169,2,218,4,115,101,
+ 108,102,114,17,0,0,0,114,10,0,0,0,114,10,0,0,
+ 0,114,11,0,0,0,218,8,95,95,105,110,105,116,95,95,
+ 58,0,0,0,115,12,0,0,0,0,1,10,1,10,1,6,
+ 1,6,1,6,1,122,20,95,77,111,100,117,108,101,76,111,
+ 99,107,46,95,95,105,110,105,116,95,95,99,1,0,0,0,
+ 0,0,0,0,0,0,0,0,5,0,0,0,3,0,0,0,
+ 67,0,0,0,115,88,0,0,0,116,0,160,1,161,0,125,
+ 1,124,0,106,2,125,2,116,3,131,0,125,3,116,4,160,
+ 5,124,2,161,1,125,4,124,4,100,0,117,0,114,42,100,
+ 1,83,0,124,4,106,2,125,2,124,2,124,1,107,2,114,
+ 60,100,2,83,0,124,2,124,3,118,0,114,72,100,1,83,
+ 0,124,3,160,6,124,2,161,1,1,0,113,20,100,0,83,
+ 0,41,3,78,70,84,41,7,114,23,0,0,0,218,9,103,
+ 101,116,95,105,100,101,110,116,114,26,0,0,0,218,3,115,
+ 101,116,218,12,95,98,108,111,99,107,105,110,103,95,111,110,
+ 218,3,103,101,116,218,3,97,100,100,41,5,114,30,0,0,
+ 0,90,2,109,101,218,3,116,105,100,90,4,115,101,101,110,
+ 114,24,0,0,0,114,10,0,0,0,114,10,0,0,0,114,
+ 11,0,0,0,218,12,104,97,115,95,100,101,97,100,108,111,
+ 99,107,66,0,0,0,115,24,0,0,0,0,2,8,1,6,
+ 1,6,2,10,1,8,1,4,1,6,1,8,1,4,1,8,
+ 6,4,1,122,24,95,77,111,100,117,108,101,76,111,99,107,
+ 46,104,97,115,95,100,101,97,100,108,111,99,107,99,1,0,
+ 0,0,0,0,0,0,0,0,0,0,2,0,0,0,8,0,
+ 0,0,67,0,0,0,115,210,0,0,0,116,0,160,1,161,
+ 0,125,1,124,0,116,2,124,1,60,0,122,180,124,0,106,
+ 3,143,126,1,0,124,0,106,4,100,1,107,2,115,46,124,
+ 0,106,5,124,1,107,2,114,90,124,1,124,0,95,5,124,
+ 0,4,0,106,4,100,2,55,0,2,0,95,4,87,0,100,
+ 3,4,0,4,0,131,3,1,0,87,0,116,2,124,1,61,
+ 0,100,4,83,0,124,0,160,6,161,0,114,110,116,7,100,
+ 5,124,0,22,0,131,1,130,1,124,0,106,8,160,9,100,
+ 6,161,1,114,136,124,0,4,0,106,10,100,2,55,0,2,
+ 0,95,10,87,0,100,3,4,0,4,0,131,3,1,0,110,
+ 16,49,0,115,156,48,0,1,0,1,0,1,0,89,0,1,
+ 0,124,0,106,8,160,9,161,0,1,0,124,0,106,8,160,
+ 11,161,0,1,0,113,18,87,0,116,2,124,1,61,0,110,
+ 8,116,2,124,1,61,0,48,0,100,3,83,0,41,7,122,
+ 185,10,32,32,32,32,32,32,32,32,65,99,113,117,105,114,
+ 101,32,116,104,101,32,109,111,100,117,108,101,32,108,111,99,
+ 107,46,32,32,73,102,32,97,32,112,111,116,101,110,116,105,
+ 97,108,32,100,101,97,100,108,111,99,107,32,105,115,32,100,
+ 101,116,101,99,116,101,100,44,10,32,32,32,32,32,32,32,
+ 32,97,32,95,68,101,97,100,108,111,99,107,69,114,114,111,
+ 114,32,105,115,32,114,97,105,115,101,100,46,10,32,32,32,
+ 32,32,32,32,32,79,116,104,101,114,119,105,115,101,44,32,
+ 116,104,101,32,108,111,99,107,32,105,115,32,97,108,119,97,
+ 121,115,32,97,99,113,117,105,114,101,100,32,97,110,100,32,
+ 84,114,117,101,32,105,115,32,114,101,116,117,114,110,101,100,
+ 46,10,32,32,32,32,32,32,32,32,114,22,0,0,0,233,
+ 1,0,0,0,78,84,122,23,100,101,97,100,108,111,99,107,
+ 32,100,101,116,101,99,116,101,100,32,98,121,32,37,114,70,
+ 41,12,114,23,0,0,0,114,32,0,0,0,114,34,0,0,
+ 0,114,24,0,0,0,114,27,0,0,0,114,26,0,0,0,
+ 114,38,0,0,0,114,19,0,0,0,114,25,0,0,0,218,
+ 7,97,99,113,117,105,114,101,114,28,0,0,0,218,7,114,
+ 101,108,101,97,115,101,169,2,114,30,0,0,0,114,37,0,
+ 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+ 0,114,40,0,0,0,87,0,0,0,115,34,0,0,0,0,
+ 6,8,1,8,1,2,2,8,1,20,1,6,1,14,1,14,
+ 9,6,247,4,1,8,1,12,1,12,1,44,2,10,1,14,
+ 2,122,19,95,77,111,100,117,108,101,76,111,99,107,46,97,
+ 99,113,117,105,114,101,99,1,0,0,0,0,0,0,0,0,
+ 0,0,0,2,0,0,0,8,0,0,0,67,0,0,0,115,
+ 142,0,0,0,116,0,160,1,161,0,125,1,124,0,106,2,
+ 143,108,1,0,124,0,106,3,124,1,107,3,114,34,116,4,
+ 100,1,131,1,130,1,124,0,106,5,100,2,107,4,115,48,
+ 74,0,130,1,124,0,4,0,106,5,100,3,56,0,2,0,
+ 95,5,124,0,106,5,100,2,107,2,114,108,100,0,124,0,
+ 95,3,124,0,106,6,114,108,124,0,4,0,106,6,100,3,
+ 56,0,2,0,95,6,124,0,106,7,160,8,161,0,1,0,
+ 87,0,100,0,4,0,4,0,131,3,1,0,110,16,49,0,
+ 115,128,48,0,1,0,1,0,1,0,89,0,1,0,100,0,
+ 83,0,41,4,78,250,31,99,97,110,110,111,116,32,114,101,
+ 108,101,97,115,101,32,117,110,45,97,99,113,117,105,114,101,
+ 100,32,108,111,99,107,114,22,0,0,0,114,39,0,0,0,
+ 41,9,114,23,0,0,0,114,32,0,0,0,114,24,0,0,
+ 0,114,26,0,0,0,218,12,82,117,110,116,105,109,101,69,
+ 114,114,111,114,114,27,0,0,0,114,28,0,0,0,114,25,
+ 0,0,0,114,41,0,0,0,114,42,0,0,0,114,10,0,
+ 0,0,114,10,0,0,0,114,11,0,0,0,114,41,0,0,
+ 0,112,0,0,0,115,22,0,0,0,0,1,8,1,8,1,
+ 10,1,8,1,14,1,14,1,10,1,6,1,6,1,14,1,
+ 122,19,95,77,111,100,117,108,101,76,111,99,107,46,114,101,
+ 108,101,97,115,101,99,1,0,0,0,0,0,0,0,0,0,
+ 0,0,1,0,0,0,5,0,0,0,67,0,0,0,115,18,
+ 0,0,0,100,1,160,0,124,0,106,1,116,2,124,0,131,
+ 1,161,2,83,0,41,2,78,122,23,95,77,111,100,117,108,
+ 101,76,111,99,107,40,123,33,114,125,41,32,97,116,32,123,
+ 125,169,3,218,6,102,111,114,109,97,116,114,17,0,0,0,
+ 218,2,105,100,169,1,114,30,0,0,0,114,10,0,0,0,
+ 114,10,0,0,0,114,11,0,0,0,218,8,95,95,114,101,
+ 112,114,95,95,125,0,0,0,115,2,0,0,0,0,1,122,
+ 20,95,77,111,100,117,108,101,76,111,99,107,46,95,95,114,
+ 101,112,114,95,95,78,41,9,114,1,0,0,0,114,0,0,
+ 0,0,114,2,0,0,0,114,3,0,0,0,114,31,0,0,
+ 0,114,38,0,0,0,114,40,0,0,0,114,41,0,0,0,
+ 114,49,0,0,0,114,10,0,0,0,114,10,0,0,0,114,
+ 10,0,0,0,114,11,0,0,0,114,20,0,0,0,52,0,
+ 0,0,115,12,0,0,0,8,1,4,5,8,8,8,21,8,
+ 25,8,13,114,20,0,0,0,99,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,2,0,0,0,64,0,0,
+ 0,115,48,0,0,0,101,0,90,1,100,0,90,2,100,1,
+ 90,3,100,2,100,3,132,0,90,4,100,4,100,5,132,0,
+ 90,5,100,6,100,7,132,0,90,6,100,8,100,9,132,0,
+ 90,7,100,10,83,0,41,11,218,16,95,68,117,109,109,121,
+ 77,111,100,117,108,101,76,111,99,107,122,86,65,32,115,105,
+ 109,112,108,101,32,95,77,111,100,117,108,101,76,111,99,107,
+ 32,101,113,117,105,118,97,108,101,110,116,32,102,111,114,32,
+ 80,121,116,104,111,110,32,98,117,105,108,100,115,32,119,105,
+ 116,104,111,117,116,10,32,32,32,32,109,117,108,116,105,45,
+ 116,104,114,101,97,100,105,110,103,32,115,117,112,112,111,114,
+ 116,46,99,2,0,0,0,0,0,0,0,0,0,0,0,2,
+ 0,0,0,2,0,0,0,67,0,0,0,115,16,0,0,0,
+ 124,1,124,0,95,0,100,1,124,0,95,1,100,0,83,0,
+ 114,21,0,0,0,41,2,114,17,0,0,0,114,27,0,0,
+ 0,114,29,0,0,0,114,10,0,0,0,114,10,0,0,0,
+ 114,11,0,0,0,114,31,0,0,0,133,0,0,0,115,4,
+ 0,0,0,0,1,6,1,122,25,95,68,117,109,109,121,77,
+ 111,100,117,108,101,76,111,99,107,46,95,95,105,110,105,116,
+ 95,95,99,1,0,0,0,0,0,0,0,0,0,0,0,1,
+ 0,0,0,3,0,0,0,67,0,0,0,115,18,0,0,0,
+ 124,0,4,0,106,0,100,1,55,0,2,0,95,0,100,2,
+ 83,0,41,3,78,114,39,0,0,0,84,41,1,114,27,0,
+ 0,0,114,48,0,0,0,114,10,0,0,0,114,10,0,0,
+ 0,114,11,0,0,0,114,40,0,0,0,137,0,0,0,115,
+ 4,0,0,0,0,1,14,1,122,24,95,68,117,109,109,121,
+ 77,111,100,117,108,101,76,111,99,107,46,97,99,113,117,105,
+ 114,101,99,1,0,0,0,0,0,0,0,0,0,0,0,1,
+ 0,0,0,3,0,0,0,67,0,0,0,115,36,0,0,0,
+ 124,0,106,0,100,1,107,2,114,18,116,1,100,2,131,1,
+ 130,1,124,0,4,0,106,0,100,3,56,0,2,0,95,0,
+ 100,0,83,0,41,4,78,114,22,0,0,0,114,43,0,0,
+ 0,114,39,0,0,0,41,2,114,27,0,0,0,114,44,0,
+ 0,0,114,48,0,0,0,114,10,0,0,0,114,10,0,0,
+ 0,114,11,0,0,0,114,41,0,0,0,141,0,0,0,115,
+ 6,0,0,0,0,1,10,1,8,1,122,24,95,68,117,109,
+ 109,121,77,111,100,117,108,101,76,111,99,107,46,114,101,108,
+ 101,97,115,101,99,1,0,0,0,0,0,0,0,0,0,0,
+ 0,1,0,0,0,5,0,0,0,67,0,0,0,115,18,0,
+ 0,0,100,1,160,0,124,0,106,1,116,2,124,0,131,1,
+ 161,2,83,0,41,2,78,122,28,95,68,117,109,109,121,77,
+ 111,100,117,108,101,76,111,99,107,40,123,33,114,125,41,32,
+ 97,116,32,123,125,114,45,0,0,0,114,48,0,0,0,114,
+ 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,49,
+ 0,0,0,146,0,0,0,115,2,0,0,0,0,1,122,25,
+ 95,68,117,109,109,121,77,111,100,117,108,101,76,111,99,107,
+ 46,95,95,114,101,112,114,95,95,78,41,8,114,1,0,0,
+ 0,114,0,0,0,0,114,2,0,0,0,114,3,0,0,0,
+ 114,31,0,0,0,114,40,0,0,0,114,41,0,0,0,114,
+ 49,0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,
+ 0,0,0,114,11,0,0,0,114,50,0,0,0,129,0,0,
+ 0,115,10,0,0,0,8,1,4,3,8,4,8,4,8,5,
+ 114,50,0,0,0,99,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,2,0,0,0,64,0,0,0,115,36,
+ 0,0,0,101,0,90,1,100,0,90,2,100,1,100,2,132,
+ 0,90,3,100,3,100,4,132,0,90,4,100,5,100,6,132,
+ 0,90,5,100,7,83,0,41,8,218,18,95,77,111,100,117,
+ 108,101,76,111,99,107,77,97,110,97,103,101,114,99,2,0,
+ 0,0,0,0,0,0,0,0,0,0,2,0,0,0,2,0,
+ 0,0,67,0,0,0,115,16,0,0,0,124,1,124,0,95,
+ 0,100,0,124,0,95,1,100,0,83,0,114,13,0,0,0,
+ 41,2,218,5,95,110,97,109,101,218,5,95,108,111,99,107,
+ 114,29,0,0,0,114,10,0,0,0,114,10,0,0,0,114,
+ 11,0,0,0,114,31,0,0,0,152,0,0,0,115,4,0,
+ 0,0,0,1,6,1,122,27,95,77,111,100,117,108,101,76,
+ 111,99,107,77,97,110,97,103,101,114,46,95,95,105,110,105,
+ 116,95,95,99,1,0,0,0,0,0,0,0,0,0,0,0,
+ 1,0,0,0,2,0,0,0,67,0,0,0,115,26,0,0,
+ 0,116,0,124,0,106,1,131,1,124,0,95,2,124,0,106,
+ 2,160,3,161,0,1,0,100,0,83,0,114,13,0,0,0,
+ 41,4,218,16,95,103,101,116,95,109,111,100,117,108,101,95,
+ 108,111,99,107,114,52,0,0,0,114,53,0,0,0,114,40,
+ 0,0,0,114,48,0,0,0,114,10,0,0,0,114,10,0,
+ 0,0,114,11,0,0,0,218,9,95,95,101,110,116,101,114,
+ 95,95,156,0,0,0,115,4,0,0,0,0,1,12,1,122,
+ 28,95,77,111,100,117,108,101,76,111,99,107,77,97,110,97,
+ 103,101,114,46,95,95,101,110,116,101,114,95,95,99,1,0,
+ 0,0,0,0,0,0,0,0,0,0,3,0,0,0,2,0,
+ 0,0,79,0,0,0,115,14,0,0,0,124,0,106,0,160,
+ 1,161,0,1,0,100,0,83,0,114,13,0,0,0,41,2,
+ 114,53,0,0,0,114,41,0,0,0,41,3,114,30,0,0,
+ 0,218,4,97,114,103,115,90,6,107,119,97,114,103,115,114,
+ 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,8,
+ 95,95,101,120,105,116,95,95,160,0,0,0,115,2,0,0,
+ 0,0,1,122,27,95,77,111,100,117,108,101,76,111,99,107,
+ 77,97,110,97,103,101,114,46,95,95,101,120,105,116,95,95,
+ 78,41,6,114,1,0,0,0,114,0,0,0,0,114,2,0,
+ 0,0,114,31,0,0,0,114,55,0,0,0,114,57,0,0,
+ 0,114,10,0,0,0,114,10,0,0,0,114,10,0,0,0,
+ 114,11,0,0,0,114,51,0,0,0,150,0,0,0,115,6,
+ 0,0,0,8,2,8,4,8,4,114,51,0,0,0,99,1,
+ 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,8,
+ 0,0,0,67,0,0,0,115,136,0,0,0,116,0,160,1,
+ 161,0,1,0,122,112,122,14,116,2,124,0,25,0,131,0,
+ 125,1,87,0,110,22,4,0,116,3,121,46,1,0,1,0,
+ 1,0,100,1,125,1,89,0,110,2,48,0,124,1,100,1,
+ 117,0,114,110,116,4,100,1,117,0,114,74,116,5,124,0,
+ 131,1,125,1,110,8,116,6,124,0,131,1,125,1,124,0,
+ 102,1,100,2,100,3,132,1,125,2,116,7,160,8,124,1,
+ 124,2,161,2,116,2,124,0,60,0,87,0,116,0,160,9,
+ 161,0,1,0,110,10,116,0,160,9,161,0,1,0,48,0,
+ 124,1,83,0,41,4,122,139,71,101,116,32,111,114,32,99,
+ 114,101,97,116,101,32,116,104,101,32,109,111,100,117,108,101,
+ 32,108,111,99,107,32,102,111,114,32,97,32,103,105,118,101,
+ 110,32,109,111,100,117,108,101,32,110,97,109,101,46,10,10,
+ 32,32,32,32,65,99,113,117,105,114,101,47,114,101,108,101,
+ 97,115,101,32,105,110,116,101,114,110,97,108,108,121,32,116,
+ 104,101,32,103,108,111,98,97,108,32,105,109,112,111,114,116,
+ 32,108,111,99,107,32,116,111,32,112,114,111,116,101,99,116,
+ 10,32,32,32,32,95,109,111,100,117,108,101,95,108,111,99,
+ 107,115,46,78,99,2,0,0,0,0,0,0,0,0,0,0,
+ 0,2,0,0,0,8,0,0,0,83,0,0,0,115,56,0,
+ 0,0,116,0,160,1,161,0,1,0,122,32,116,2,160,3,
+ 124,1,161,1,124,0,117,0,114,30,116,2,124,1,61,0,
+ 87,0,116,0,160,4,161,0,1,0,110,10,116,0,160,4,
+ 161,0,1,0,48,0,100,0,83,0,114,13,0,0,0,41,
+ 5,218,4,95,105,109,112,218,12,97,99,113,117,105,114,101,
+ 95,108,111,99,107,218,13,95,109,111,100,117,108,101,95,108,
+ 111,99,107,115,114,35,0,0,0,218,12,114,101,108,101,97,
+ 115,101,95,108,111,99,107,41,2,218,3,114,101,102,114,17,
+ 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,
+ 0,0,218,2,99,98,185,0,0,0,115,10,0,0,0,0,
+ 1,8,1,2,4,14,1,8,2,122,28,95,103,101,116,95,
+ 109,111,100,117,108,101,95,108,111,99,107,46,60,108,111,99,
+ 97,108,115,62,46,99,98,41,10,114,58,0,0,0,114,59,
+ 0,0,0,114,60,0,0,0,218,8,75,101,121,69,114,114,
+ 111,114,114,23,0,0,0,114,50,0,0,0,114,20,0,0,
+ 0,218,8,95,119,101,97,107,114,101,102,114,62,0,0,0,
+ 114,61,0,0,0,41,3,114,17,0,0,0,114,24,0,0,
+ 0,114,63,0,0,0,114,10,0,0,0,114,10,0,0,0,
+ 114,11,0,0,0,114,54,0,0,0,166,0,0,0,115,28,
+ 0,0,0,0,6,8,1,2,1,2,1,14,1,12,1,10,
+ 2,8,1,8,1,10,2,8,2,12,11,18,2,20,2,114,
+ 54,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,
+ 0,2,0,0,0,8,0,0,0,67,0,0,0,115,52,0,
+ 0,0,116,0,124,0,131,1,125,1,122,12,124,1,160,1,
+ 161,0,1,0,87,0,110,18,4,0,116,2,121,38,1,0,
+ 1,0,1,0,89,0,110,10,48,0,124,1,160,3,161,0,
+ 1,0,100,1,83,0,41,2,122,189,65,99,113,117,105,114,
+ 101,115,32,116,104,101,110,32,114,101,108,101,97,115,101,115,
+ 32,116,104,101,32,109,111,100,117,108,101,32,108,111,99,107,
+ 32,102,111,114,32,97,32,103,105,118,101,110,32,109,111,100,
+ 117,108,101,32,110,97,109,101,46,10,10,32,32,32,32,84,
+ 104,105,115,32,105,115,32,117,115,101,100,32,116,111,32,101,
+ 110,115,117,114,101,32,97,32,109,111,100,117,108,101,32,105,
+ 115,32,99,111,109,112,108,101,116,101,108,121,32,105,110,105,
+ 116,105,97,108,105,122,101,100,44,32,105,110,32,116,104,101,
+ 10,32,32,32,32,101,118,101,110,116,32,105,116,32,105,115,
+ 32,98,101,105,110,103,32,105,109,112,111,114,116,101,100,32,
+ 98,121,32,97,110,111,116,104,101,114,32,116,104,114,101,97,
+ 100,46,10,32,32,32,32,78,41,4,114,54,0,0,0,114,
+ 40,0,0,0,114,19,0,0,0,114,41,0,0,0,41,2,
+ 114,17,0,0,0,114,24,0,0,0,114,10,0,0,0,114,
+ 10,0,0,0,114,11,0,0,0,218,19,95,108,111,99,107,
+ 95,117,110,108,111,99,107,95,109,111,100,117,108,101,203,0,
+ 0,0,115,12,0,0,0,0,6,8,1,2,1,12,1,12,
+ 3,6,2,114,66,0,0,0,99,1,0,0,0,0,0,0,
+ 0,0,0,0,0,3,0,0,0,4,0,0,0,79,0,0,
+ 0,115,14,0,0,0,124,0,124,1,105,0,124,2,164,1,
+ 142,1,83,0,41,1,97,46,1,0,0,114,101,109,111,118,
+ 101,95,105,109,112,111,114,116,108,105,98,95,102,114,97,109,
+ 101,115,32,105,110,32,105,109,112,111,114,116,46,99,32,119,
+ 105,108,108,32,97,108,119,97,121,115,32,114,101,109,111,118,
+ 101,32,115,101,113,117,101,110,99,101,115,10,32,32,32,32,
+ 111,102,32,105,109,112,111,114,116,108,105,98,32,102,114,97,
+ 109,101,115,32,116,104,97,116,32,101,110,100,32,119,105,116,
+ 104,32,97,32,99,97,108,108,32,116,111,32,116,104,105,115,
+ 32,102,117,110,99,116,105,111,110,10,10,32,32,32,32,85,
+ 115,101,32,105,116,32,105,110,115,116,101,97,100,32,111,102,
+ 32,97,32,110,111,114,109,97,108,32,99,97,108,108,32,105,
+ 110,32,112,108,97,99,101,115,32,119,104,101,114,101,32,105,
+ 110,99,108,117,100,105,110,103,32,116,104,101,32,105,109,112,
+ 111,114,116,108,105,98,10,32,32,32,32,102,114,97,109,101,
+ 115,32,105,110,116,114,111,100,117,99,101,115,32,117,110,119,
+ 97,110,116,101,100,32,110,111,105,115,101,32,105,110,116,111,
+ 32,116,104,101,32,116,114,97,99,101,98,97,99,107,32,40,
+ 101,46,103,46,32,119,104,101,110,32,101,120,101,99,117,116,
+ 105,110,103,10,32,32,32,32,109,111,100,117,108,101,32,99,
+ 111,100,101,41,10,32,32,32,32,114,10,0,0,0,41,3,
+ 218,1,102,114,56,0,0,0,90,4,107,119,100,115,114,10,
+ 0,0,0,114,10,0,0,0,114,11,0,0,0,218,25,95,
+ 99,97,108,108,95,119,105,116,104,95,102,114,97,109,101,115,
+ 95,114,101,109,111,118,101,100,220,0,0,0,115,2,0,0,
+ 0,0,8,114,68,0,0,0,114,39,0,0,0,41,1,218,
+ 9,118,101,114,98,111,115,105,116,121,99,1,0,0,0,0,
+ 0,0,0,1,0,0,0,3,0,0,0,4,0,0,0,71,
+ 0,0,0,115,54,0,0,0,116,0,106,1,106,2,124,1,
+ 107,5,114,50,124,0,160,3,100,1,161,1,115,30,100,2,
+ 124,0,23,0,125,0,116,4,124,0,106,5,124,2,142,0,
+ 116,0,106,6,100,3,141,2,1,0,100,4,83,0,41,5,
+ 122,61,80,114,105,110,116,32,116,104,101,32,109,101,115,115,
+ 97,103,101,32,116,111,32,115,116,100,101,114,114,32,105,102,
+ 32,45,118,47,80,89,84,72,79,78,86,69,82,66,79,83,
+ 69,32,105,115,32,116,117,114,110,101,100,32,111,110,46,41,
+ 2,250,1,35,122,7,105,109,112,111,114,116,32,122,2,35,
+ 32,41,1,90,4,102,105,108,101,78,41,7,114,15,0,0,
+ 0,218,5,102,108,97,103,115,218,7,118,101,114,98,111,115,
+ 101,218,10,115,116,97,114,116,115,119,105,116,104,218,5,112,
+ 114,105,110,116,114,46,0,0,0,218,6,115,116,100,101,114,
+ 114,41,3,218,7,109,101,115,115,97,103,101,114,69,0,0,
+ 0,114,56,0,0,0,114,10,0,0,0,114,10,0,0,0,
+ 114,11,0,0,0,218,16,95,118,101,114,98,111,115,101,95,
+ 109,101,115,115,97,103,101,231,0,0,0,115,8,0,0,0,
+ 0,2,12,1,10,1,8,1,114,77,0,0,0,99,1,0,
+ 0,0,0,0,0,0,0,0,0,0,2,0,0,0,3,0,
+ 0,0,3,0,0,0,115,26,0,0,0,135,0,102,1,100,
+ 1,100,2,132,8,125,1,116,0,124,1,136,0,131,2,1,
+ 0,124,1,83,0,41,3,122,49,68,101,99,111,114,97,116,
+ 111,114,32,116,111,32,118,101,114,105,102,121,32,116,104,101,
+ 32,110,97,109,101,100,32,109,111,100,117,108,101,32,105,115,
+ 32,98,117,105,108,116,45,105,110,46,99,2,0,0,0,0,
+ 0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,19,
+ 0,0,0,115,38,0,0,0,124,1,116,0,106,1,118,1,
+ 114,28,116,2,100,1,160,3,124,1,161,1,124,1,100,2,
+ 141,2,130,1,136,0,124,0,124,1,131,2,83,0,41,3,
+ 78,250,29,123,33,114,125,32,105,115,32,110,111,116,32,97,
+ 32,98,117,105,108,116,45,105,110,32,109,111,100,117,108,101,
+ 114,16,0,0,0,41,4,114,15,0,0,0,218,20,98,117,
+ 105,108,116,105,110,95,109,111,100,117,108,101,95,110,97,109,
+ 101,115,218,11,73,109,112,111,114,116,69,114,114,111,114,114,
+ 46,0,0,0,169,2,114,30,0,0,0,218,8,102,117,108,
+ 108,110,97,109,101,169,1,218,3,102,120,110,114,10,0,0,
+ 0,114,11,0,0,0,218,25,95,114,101,113,117,105,114,101,
+ 115,95,98,117,105,108,116,105,110,95,119,114,97,112,112,101,
+ 114,241,0,0,0,115,10,0,0,0,0,1,10,1,10,1,
+ 2,255,6,2,122,52,95,114,101,113,117,105,114,101,115,95,
+ 98,117,105,108,116,105,110,46,60,108,111,99,97,108,115,62,
+ 46,95,114,101,113,117,105,114,101,115,95,98,117,105,108,116,
+ 105,110,95,119,114,97,112,112,101,114,169,1,114,12,0,0,
+ 0,41,2,114,84,0,0,0,114,85,0,0,0,114,10,0,
+ 0,0,114,83,0,0,0,114,11,0,0,0,218,17,95,114,
+ 101,113,117,105,114,101,115,95,98,117,105,108,116,105,110,239,
+ 0,0,0,115,6,0,0,0,0,2,12,5,10,1,114,87,
+ 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,
+ 2,0,0,0,3,0,0,0,3,0,0,0,115,26,0,0,
+ 0,135,0,102,1,100,1,100,2,132,8,125,1,116,0,124,
+ 1,136,0,131,2,1,0,124,1,83,0,41,3,122,47,68,
+ 101,99,111,114,97,116,111,114,32,116,111,32,118,101,114,105,
+ 102,121,32,116,104,101,32,110,97,109,101,100,32,109,111,100,
+ 117,108,101,32,105,115,32,102,114,111,122,101,110,46,99,2,
+ 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,4,
+ 0,0,0,19,0,0,0,115,38,0,0,0,116,0,160,1,
+ 124,1,161,1,115,28,116,2,100,1,160,3,124,1,161,1,
+ 124,1,100,2,141,2,130,1,136,0,124,0,124,1,131,2,
+ 83,0,169,3,78,122,27,123,33,114,125,32,105,115,32,110,
+ 111,116,32,97,32,102,114,111,122,101,110,32,109,111,100,117,
+ 108,101,114,16,0,0,0,41,4,114,58,0,0,0,218,9,
+ 105,115,95,102,114,111,122,101,110,114,80,0,0,0,114,46,
+ 0,0,0,114,81,0,0,0,114,83,0,0,0,114,10,0,
+ 0,0,114,11,0,0,0,218,24,95,114,101,113,117,105,114,
+ 101,115,95,102,114,111,122,101,110,95,119,114,97,112,112,101,
+ 114,252,0,0,0,115,10,0,0,0,0,1,10,1,10,1,
+ 2,255,6,2,122,50,95,114,101,113,117,105,114,101,115,95,
+ 102,114,111,122,101,110,46,60,108,111,99,97,108,115,62,46,
+ 95,114,101,113,117,105,114,101,115,95,102,114,111,122,101,110,
+ 95,119,114,97,112,112,101,114,114,86,0,0,0,41,2,114,
+ 84,0,0,0,114,90,0,0,0,114,10,0,0,0,114,83,
+ 0,0,0,114,11,0,0,0,218,16,95,114,101,113,117,105,
+ 114,101,115,95,102,114,111,122,101,110,250,0,0,0,115,6,
+ 0,0,0,0,2,12,5,10,1,114,91,0,0,0,99,2,
+ 0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,3,
+ 0,0,0,67,0,0,0,115,62,0,0,0,116,0,124,1,
+ 124,0,131,2,125,2,124,1,116,1,106,2,118,0,114,50,
+ 116,1,106,2,124,1,25,0,125,3,116,3,124,2,124,3,
+ 131,2,1,0,116,1,106,2,124,1,25,0,83,0,116,4,
+ 124,2,131,1,83,0,100,1,83,0,41,2,122,128,76,111,
+ 97,100,32,116,104,101,32,115,112,101,99,105,102,105,101,100,
+ 32,109,111,100,117,108,101,32,105,110,116,111,32,115,121,115,
+ 46,109,111,100,117,108,101,115,32,97,110,100,32,114,101,116,
+ 117,114,110,32,105,116,46,10,10,32,32,32,32,84,104,105,
+ 115,32,109,101,116,104,111,100,32,105,115,32,100,101,112,114,
+ 101,99,97,116,101,100,46,32,32,85,115,101,32,108,111,97,
+ 100,101,114,46,101,120,101,99,95,109,111,100,117,108,101,32,
+ 105,110,115,116,101,97,100,46,10,10,32,32,32,32,78,41,
+ 5,218,16,115,112,101,99,95,102,114,111,109,95,108,111,97,
+ 100,101,114,114,15,0,0,0,218,7,109,111,100,117,108,101,
+ 115,218,5,95,101,120,101,99,218,5,95,108,111,97,100,41,
+ 4,114,30,0,0,0,114,82,0,0,0,218,4,115,112,101,
+ 99,218,6,109,111,100,117,108,101,114,10,0,0,0,114,10,
+ 0,0,0,114,11,0,0,0,218,17,95,108,111,97,100,95,
+ 109,111,100,117,108,101,95,115,104,105,109,6,1,0,0,115,
+ 12,0,0,0,0,6,10,1,10,1,10,1,10,1,10,2,
+ 114,98,0,0,0,99,1,0,0,0,0,0,0,0,0,0,
+ 0,0,5,0,0,0,8,0,0,0,67,0,0,0,115,218,
+ 0,0,0,116,0,124,0,100,1,100,0,131,3,125,1,116,
+ 1,124,1,100,2,131,2,114,54,122,12,124,1,160,2,124,
+ 0,161,1,87,0,83,0,4,0,116,3,121,52,1,0,1,
+ 0,1,0,89,0,110,2,48,0,122,10,124,0,106,4,125,
+ 2,87,0,110,18,4,0,116,5,121,82,1,0,1,0,1,
+ 0,89,0,110,18,48,0,124,2,100,0,117,1,114,100,116,
+ 6,124,2,131,1,83,0,122,10,124,0,106,7,125,3,87,
+ 0,110,22,4,0,116,5,121,132,1,0,1,0,1,0,100,
+ 3,125,3,89,0,110,2,48,0,122,10,124,0,106,8,125,
+ 4,87,0,110,56,4,0,116,5,121,200,1,0,1,0,1,
+ 0,124,1,100,0,117,0,114,180,100,4,160,9,124,3,161,
+ 1,6,0,89,0,83,0,100,5,160,9,124,3,124,1,161,
+ 2,6,0,89,0,83,0,89,0,110,14,48,0,100,6,160,
+ 9,124,3,124,4,161,2,83,0,100,0,83,0,41,7,78,
+ 218,10,95,95,108,111,97,100,101,114,95,95,218,11,109,111,
+ 100,117,108,101,95,114,101,112,114,250,1,63,250,13,60,109,
+ 111,100,117,108,101,32,123,33,114,125,62,250,20,60,109,111,
+ 100,117,108,101,32,123,33,114,125,32,40,123,33,114,125,41,
+ 62,250,23,60,109,111,100,117,108,101,32,123,33,114,125,32,
+ 102,114,111,109,32,123,33,114,125,62,41,10,114,6,0,0,
+ 0,114,4,0,0,0,114,100,0,0,0,218,9,69,120,99,
+ 101,112,116,105,111,110,218,8,95,95,115,112,101,99,95,95,
+ 218,14,65,116,116,114,105,98,117,116,101,69,114,114,111,114,
+ 218,22,95,109,111,100,117,108,101,95,114,101,112,114,95,102,
+ 114,111,109,95,115,112,101,99,114,1,0,0,0,218,8,95,
+ 95,102,105,108,101,95,95,114,46,0,0,0,41,5,114,97,
+ 0,0,0,218,6,108,111,97,100,101,114,114,96,0,0,0,
+ 114,17,0,0,0,218,8,102,105,108,101,110,97,109,101,114,
+ 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,12,
+ 95,109,111,100,117,108,101,95,114,101,112,114,22,1,0,0,
+ 115,46,0,0,0,0,2,12,1,10,4,2,1,12,1,12,
+ 1,6,1,2,1,10,1,12,1,6,2,8,1,8,4,2,
+ 1,10,1,12,1,10,1,2,1,10,1,12,1,8,1,14,
+ 2,22,2,114,112,0,0,0,99,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,4,0,0,0,64,0,0,
+ 0,115,114,0,0,0,101,0,90,1,100,0,90,2,100,1,
+ 90,3,100,2,100,2,100,2,100,3,156,3,100,4,100,5,
+ 132,2,90,4,100,6,100,7,132,0,90,5,100,8,100,9,
+ 132,0,90,6,101,7,100,10,100,11,132,0,131,1,90,8,
+ 101,8,106,9,100,12,100,11,132,0,131,1,90,8,101,7,
+ 100,13,100,14,132,0,131,1,90,10,101,7,100,15,100,16,
+ 132,0,131,1,90,11,101,11,106,9,100,17,100,16,132,0,
+ 131,1,90,11,100,2,83,0,41,18,218,10,77,111,100,117,
+ 108,101,83,112,101,99,97,208,5,0,0,84,104,101,32,115,
+ 112,101,99,105,102,105,99,97,116,105,111,110,32,102,111,114,
+ 32,97,32,109,111,100,117,108,101,44,32,117,115,101,100,32,
+ 102,111,114,32,108,111,97,100,105,110,103,46,10,10,32,32,
+ 32,32,65,32,109,111,100,117,108,101,39,115,32,115,112,101,
+ 99,32,105,115,32,116,104,101,32,115,111,117,114,99,101,32,
+ 102,111,114,32,105,110,102,111,114,109,97,116,105,111,110,32,
+ 97,98,111,117,116,32,116,104,101,32,109,111,100,117,108,101,
+ 46,32,32,70,111,114,10,32,32,32,32,100,97,116,97,32,
+ 97,115,115,111,99,105,97,116,101,100,32,119,105,116,104,32,
+ 116,104,101,32,109,111,100,117,108,101,44,32,105,110,99,108,
+ 117,100,105,110,103,32,115,111,117,114,99,101,44,32,117,115,
+ 101,32,116,104,101,32,115,112,101,99,39,115,10,32,32,32,
+ 32,108,111,97,100,101,114,46,10,10,32,32,32,32,96,110,
+ 97,109,101,96,32,105,115,32,116,104,101,32,97,98,115,111,
+ 108,117,116,101,32,110,97,109,101,32,111,102,32,116,104,101,
+ 32,109,111,100,117,108,101,46,32,32,96,108,111,97,100,101,
+ 114,96,32,105,115,32,116,104,101,32,108,111,97,100,101,114,
+ 10,32,32,32,32,116,111,32,117,115,101,32,119,104,101,110,
+ 32,108,111,97,100,105,110,103,32,116,104,101,32,109,111,100,
+ 117,108,101,46,32,32,96,112,97,114,101,110,116,96,32,105,
+ 115,32,116,104,101,32,110,97,109,101,32,111,102,32,116,104,
+ 101,10,32,32,32,32,112,97,99,107,97,103,101,32,116,104,
+ 101,32,109,111,100,117,108,101,32,105,115,32,105,110,46,32,
+ 32,84,104,101,32,112,97,114,101,110,116,32,105,115,32,100,
+ 101,114,105,118,101,100,32,102,114,111,109,32,116,104,101,32,
+ 110,97,109,101,46,10,10,32,32,32,32,96,105,115,95,112,
+ 97,99,107,97,103,101,96,32,100,101,116,101,114,109,105,110,
+ 101,115,32,105,102,32,116,104,101,32,109,111,100,117,108,101,
+ 32,105,115,32,99,111,110,115,105,100,101,114,101,100,32,97,
+ 32,112,97,99,107,97,103,101,32,111,114,10,32,32,32,32,
+ 110,111,116,46,32,32,79,110,32,109,111,100,117,108,101,115,
+ 32,116,104,105,115,32,105,115,32,114,101,102,108,101,99,116,
+ 101,100,32,98,121,32,116,104,101,32,96,95,95,112,97,116,
+ 104,95,95,96,32,97,116,116,114,105,98,117,116,101,46,10,
+ 10,32,32,32,32,96,111,114,105,103,105,110,96,32,105,115,
+ 32,116,104,101,32,115,112,101,99,105,102,105,99,32,108,111,
+ 99,97,116,105,111,110,32,117,115,101,100,32,98,121,32,116,
+ 104,101,32,108,111,97,100,101,114,32,102,114,111,109,32,119,
+ 104,105,99,104,32,116,111,10,32,32,32,32,108,111,97,100,
+ 32,116,104,101,32,109,111,100,117,108,101,44,32,105,102,32,
+ 116,104,97,116,32,105,110,102,111,114,109,97,116,105,111,110,
+ 32,105,115,32,97,118,97,105,108,97,98,108,101,46,32,32,
+ 87,104,101,110,32,102,105,108,101,110,97,109,101,32,105,115,
+ 10,32,32,32,32,115,101,116,44,32,111,114,105,103,105,110,
+ 32,119,105,108,108,32,109,97,116,99,104,46,10,10,32,32,
+ 32,32,96,104,97,115,95,108,111,99,97,116,105,111,110,96,
+ 32,105,110,100,105,99,97,116,101,115,32,116,104,97,116,32,
+ 97,32,115,112,101,99,39,115,32,34,111,114,105,103,105,110,
+ 34,32,114,101,102,108,101,99,116,115,32,97,32,108,111,99,
+ 97,116,105,111,110,46,10,32,32,32,32,87,104,101,110,32,
+ 116,104,105,115,32,105,115,32,84,114,117,101,44,32,96,95,
+ 95,102,105,108,101,95,95,96,32,97,116,116,114,105,98,117,
+ 116,101,32,111,102,32,116,104,101,32,109,111,100,117,108,101,
+ 32,105,115,32,115,101,116,46,10,10,32,32,32,32,96,99,
+ 97,99,104,101,100,96,32,105,115,32,116,104,101,32,108,111,
+ 99,97,116,105,111,110,32,111,102,32,116,104,101,32,99,97,
+ 99,104,101,100,32,98,121,116,101,99,111,100,101,32,102,105,
+ 108,101,44,32,105,102,32,97,110,121,46,32,32,73,116,10,
+ 32,32,32,32,99,111,114,114,101,115,112,111,110,100,115,32,
+ 116,111,32,116,104,101,32,96,95,95,99,97,99,104,101,100,
+ 95,95,96,32,97,116,116,114,105,98,117,116,101,46,10,10,
+ 32,32,32,32,96,115,117,98,109,111,100,117,108,101,95,115,
+ 101,97,114,99,104,95,108,111,99,97,116,105,111,110,115,96,
+ 32,105,115,32,116,104,101,32,115,101,113,117,101,110,99,101,
+ 32,111,102,32,112,97,116,104,32,101,110,116,114,105,101,115,
+ 32,116,111,10,32,32,32,32,115,101,97,114,99,104,32,119,
+ 104,101,110,32,105,109,112,111,114,116,105,110,103,32,115,117,
+ 98,109,111,100,117,108,101,115,46,32,32,73,102,32,115,101,
+ 116,44,32,105,115,95,112,97,99,107,97,103,101,32,115,104,
+ 111,117,108,100,32,98,101,10,32,32,32,32,84,114,117,101,
+ 45,45,97,110,100,32,70,97,108,115,101,32,111,116,104,101,
+ 114,119,105,115,101,46,10,10,32,32,32,32,80,97,99,107,
+ 97,103,101,115,32,97,114,101,32,115,105,109,112,108,121,32,
+ 109,111,100,117,108,101,115,32,116,104,97,116,32,40,109,97,
+ 121,41,32,104,97,118,101,32,115,117,98,109,111,100,117,108,
+ 101,115,46,32,32,73,102,32,97,32,115,112,101,99,10,32,
+ 32,32,32,104,97,115,32,97,32,110,111,110,45,78,111,110,
+ 101,32,118,97,108,117,101,32,105,110,32,96,115,117,98,109,
+ 111,100,117,108,101,95,115,101,97,114,99,104,95,108,111,99,
+ 97,116,105,111,110,115,96,44,32,116,104,101,32,105,109,112,
+ 111,114,116,10,32,32,32,32,115,121,115,116,101,109,32,119,
+ 105,108,108,32,99,111,110,115,105,100,101,114,32,109,111,100,
+ 117,108,101,115,32,108,111,97,100,101,100,32,102,114,111,109,
+ 32,116,104,101,32,115,112,101,99,32,97,115,32,112,97,99,
+ 107,97,103,101,115,46,10,10,32,32,32,32,79,110,108,121,
+ 32,102,105,110,100,101,114,115,32,40,115,101,101,32,105,109,
+ 112,111,114,116,108,105,98,46,97,98,99,46,77,101,116,97,
+ 80,97,116,104,70,105,110,100,101,114,32,97,110,100,10,32,
+ 32,32,32,105,109,112,111,114,116,108,105,98,46,97,98,99,
+ 46,80,97,116,104,69,110,116,114,121,70,105,110,100,101,114,
+ 41,32,115,104,111,117,108,100,32,109,111,100,105,102,121,32,
+ 77,111,100,117,108,101,83,112,101,99,32,105,110,115,116,97,
+ 110,99,101,115,46,10,10,32,32,32,32,78,41,3,218,6,
+ 111,114,105,103,105,110,218,12,108,111,97,100,101,114,95,115,
+ 116,97,116,101,218,10,105,115,95,112,97,99,107,97,103,101,
+ 99,3,0,0,0,0,0,0,0,3,0,0,0,6,0,0,
+ 0,2,0,0,0,67,0,0,0,115,54,0,0,0,124,1,
+ 124,0,95,0,124,2,124,0,95,1,124,3,124,0,95,2,
+ 124,4,124,0,95,3,124,5,114,32,103,0,110,2,100,0,
+ 124,0,95,4,100,1,124,0,95,5,100,0,124,0,95,6,
+ 100,0,83,0,41,2,78,70,41,7,114,17,0,0,0,114,
+ 110,0,0,0,114,114,0,0,0,114,115,0,0,0,218,26,
+ 115,117,98,109,111,100,117,108,101,95,115,101,97,114,99,104,
+ 95,108,111,99,97,116,105,111,110,115,218,13,95,115,101,116,
+ 95,102,105,108,101,97,116,116,114,218,7,95,99,97,99,104,
+ 101,100,41,6,114,30,0,0,0,114,17,0,0,0,114,110,
+ 0,0,0,114,114,0,0,0,114,115,0,0,0,114,116,0,
+ 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+ 0,114,31,0,0,0,95,1,0,0,115,14,0,0,0,0,
+ 2,6,1,6,1,6,1,6,1,14,3,6,1,122,19,77,
+ 111,100,117,108,101,83,112,101,99,46,95,95,105,110,105,116,
+ 95,95,99,1,0,0,0,0,0,0,0,0,0,0,0,2,
+ 0,0,0,6,0,0,0,67,0,0,0,115,102,0,0,0,
+ 100,1,160,0,124,0,106,1,161,1,100,2,160,0,124,0,
+ 106,2,161,1,103,2,125,1,124,0,106,3,100,0,117,1,
+ 114,52,124,1,160,4,100,3,160,0,124,0,106,3,161,1,
+ 161,1,1,0,124,0,106,5,100,0,117,1,114,80,124,1,
+ 160,4,100,4,160,0,124,0,106,5,161,1,161,1,1,0,
+ 100,5,160,0,124,0,106,6,106,7,100,6,160,8,124,1,
+ 161,1,161,2,83,0,41,7,78,122,9,110,97,109,101,61,
+ 123,33,114,125,122,11,108,111,97,100,101,114,61,123,33,114,
+ 125,122,11,111,114,105,103,105,110,61,123,33,114,125,122,29,
+ 115,117,98,109,111,100,117,108,101,95,115,101,97,114,99,104,
+ 95,108,111,99,97,116,105,111,110,115,61,123,125,122,6,123,
+ 125,40,123,125,41,122,2,44,32,41,9,114,46,0,0,0,
+ 114,17,0,0,0,114,110,0,0,0,114,114,0,0,0,218,
+ 6,97,112,112,101,110,100,114,117,0,0,0,218,9,95,95,
+ 99,108,97,115,115,95,95,114,1,0,0,0,218,4,106,111,
+ 105,110,41,2,114,30,0,0,0,114,56,0,0,0,114,10,
+ 0,0,0,114,10,0,0,0,114,11,0,0,0,114,49,0,
+ 0,0,107,1,0,0,115,20,0,0,0,0,1,10,1,10,
+ 255,4,2,10,1,18,1,10,1,8,1,4,255,6,2,122,
+ 19,77,111,100,117,108,101,83,112,101,99,46,95,95,114,101,
+ 112,114,95,95,99,2,0,0,0,0,0,0,0,0,0,0,
+ 0,3,0,0,0,8,0,0,0,67,0,0,0,115,106,0,
+ 0,0,124,0,106,0,125,2,122,72,124,0,106,1,124,1,
+ 106,1,107,2,111,76,124,0,106,2,124,1,106,2,107,2,
+ 111,76,124,0,106,3,124,1,106,3,107,2,111,76,124,2,
+ 124,1,106,0,107,2,111,76,124,0,106,4,124,1,106,4,
+ 107,2,111,76,124,0,106,5,124,1,106,5,107,2,87,0,
+ 83,0,4,0,116,6,121,100,1,0,1,0,1,0,116,7,
+ 6,0,89,0,83,0,48,0,100,0,83,0,114,13,0,0,
+ 0,41,8,114,117,0,0,0,114,17,0,0,0,114,110,0,
+ 0,0,114,114,0,0,0,218,6,99,97,99,104,101,100,218,
+ 12,104,97,115,95,108,111,99,97,116,105,111,110,114,107,0,
+ 0,0,218,14,78,111,116,73,109,112,108,101,109,101,110,116,
+ 101,100,41,3,114,30,0,0,0,90,5,111,116,104,101,114,
+ 90,4,115,109,115,108,114,10,0,0,0,114,10,0,0,0,
+ 114,11,0,0,0,218,6,95,95,101,113,95,95,117,1,0,
+ 0,115,30,0,0,0,0,1,6,1,2,1,12,1,10,255,
+ 2,2,10,254,2,3,8,253,2,4,10,252,2,5,10,251,
+ 4,6,12,1,122,17,77,111,100,117,108,101,83,112,101,99,
+ 46,95,95,101,113,95,95,99,1,0,0,0,0,0,0,0,
+ 0,0,0,0,1,0,0,0,3,0,0,0,67,0,0,0,
+ 115,58,0,0,0,124,0,106,0,100,0,117,0,114,52,124,
+ 0,106,1,100,0,117,1,114,52,124,0,106,2,114,52,116,
+ 3,100,0,117,0,114,38,116,4,130,1,116,3,160,5,124,
+ 0,106,1,161,1,124,0,95,0,124,0,106,0,83,0,114,
+ 13,0,0,0,41,6,114,119,0,0,0,114,114,0,0,0,
+ 114,118,0,0,0,218,19,95,98,111,111,116,115,116,114,97,
+ 112,95,101,120,116,101,114,110,97,108,218,19,78,111,116,73,
+ 109,112,108,101,109,101,110,116,101,100,69,114,114,111,114,90,
+ 11,95,103,101,116,95,99,97,99,104,101,100,114,48,0,0,
+ 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
+ 114,123,0,0,0,129,1,0,0,115,12,0,0,0,0,2,
+ 10,1,16,1,8,1,4,1,14,1,122,17,77,111,100,117,
+ 108,101,83,112,101,99,46,99,97,99,104,101,100,99,2,0,
+ 0,0,0,0,0,0,0,0,0,0,2,0,0,0,2,0,
+ 0,0,67,0,0,0,115,10,0,0,0,124,1,124,0,95,
+ 0,100,0,83,0,114,13,0,0,0,41,1,114,119,0,0,
+ 0,41,2,114,30,0,0,0,114,123,0,0,0,114,10,0,
+ 0,0,114,10,0,0,0,114,11,0,0,0,114,123,0,0,
+ 0,138,1,0,0,115,2,0,0,0,0,2,99,1,0,0,
+ 0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0,
+ 0,67,0,0,0,115,36,0,0,0,124,0,106,0,100,1,
+ 117,0,114,26,124,0,106,1,160,2,100,2,161,1,100,3,
+ 25,0,83,0,124,0,106,1,83,0,100,1,83,0,41,4,
+ 122,32,84,104,101,32,110,97,109,101,32,111,102,32,116,104,
+ 101,32,109,111,100,117,108,101,39,115,32,112,97,114,101,110,
+ 116,46,78,218,1,46,114,22,0,0,0,41,3,114,117,0,
+ 0,0,114,17,0,0,0,218,10,114,112,97,114,116,105,116,
+ 105,111,110,114,48,0,0,0,114,10,0,0,0,114,10,0,
+ 0,0,114,11,0,0,0,218,6,112,97,114,101,110,116,142,
+ 1,0,0,115,6,0,0,0,0,3,10,1,16,2,122,17,
+ 77,111,100,117,108,101,83,112,101,99,46,112,97,114,101,110,
+ 116,99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,
+ 0,0,1,0,0,0,67,0,0,0,115,6,0,0,0,124,
+ 0,106,0,83,0,114,13,0,0,0,41,1,114,118,0,0,
+ 0,114,48,0,0,0,114,10,0,0,0,114,10,0,0,0,
+ 114,11,0,0,0,114,124,0,0,0,150,1,0,0,115,2,
+ 0,0,0,0,2,122,23,77,111,100,117,108,101,83,112,101,
+ 99,46,104,97,115,95,108,111,99,97,116,105,111,110,99,2,
+ 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,2,
+ 0,0,0,67,0,0,0,115,14,0,0,0,116,0,124,1,
+ 131,1,124,0,95,1,100,0,83,0,114,13,0,0,0,41,
+ 2,218,4,98,111,111,108,114,118,0,0,0,41,2,114,30,
+ 0,0,0,218,5,118,97,108,117,101,114,10,0,0,0,114,
+ 10,0,0,0,114,11,0,0,0,114,124,0,0,0,154,1,
+ 0,0,115,2,0,0,0,0,2,41,12,114,1,0,0,0,
+ 114,0,0,0,0,114,2,0,0,0,114,3,0,0,0,114,
+ 31,0,0,0,114,49,0,0,0,114,126,0,0,0,218,8,
+ 112,114,111,112,101,114,116,121,114,123,0,0,0,218,6,115,
+ 101,116,116,101,114,114,131,0,0,0,114,124,0,0,0,114,
+ 10,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,
+ 0,0,0,114,113,0,0,0,58,1,0,0,115,32,0,0,
+ 0,8,1,4,36,4,1,2,255,12,12,8,10,8,12,2,
+ 1,10,8,4,1,10,3,2,1,10,7,2,1,10,3,4,
+ 1,114,113,0,0,0,169,2,114,114,0,0,0,114,116,0,
+ 0,0,99,2,0,0,0,0,0,0,0,2,0,0,0,6,
+ 0,0,0,8,0,0,0,67,0,0,0,115,152,0,0,0,
+ 116,0,124,1,100,1,131,2,114,74,116,1,100,2,117,0,
+ 114,22,116,2,130,1,116,1,106,3,125,4,124,3,100,2,
+ 117,0,114,48,124,4,124,0,124,1,100,3,141,2,83,0,
+ 124,3,114,56,103,0,110,2,100,2,125,5,124,4,124,0,
+ 124,1,124,5,100,4,141,3,83,0,124,3,100,2,117,0,
+ 114,136,116,0,124,1,100,5,131,2,114,132,122,14,124,1,
+ 160,4,124,0,161,1,125,3,87,0,113,136,4,0,116,5,
+ 121,128,1,0,1,0,1,0,100,2,125,3,89,0,113,136,
+ 48,0,110,4,100,6,125,3,116,6,124,0,124,1,124,2,
+ 124,3,100,7,141,4,83,0,41,8,122,53,82,101,116,117,
+ 114,110,32,97,32,109,111,100,117,108,101,32,115,112,101,99,
+ 32,98,97,115,101,100,32,111,110,32,118,97,114,105,111,117,
+ 115,32,108,111,97,100,101,114,32,109,101,116,104,111,100,115,
+ 46,90,12,103,101,116,95,102,105,108,101,110,97,109,101,78,
+ 41,1,114,110,0,0,0,41,2,114,110,0,0,0,114,117,
+ 0,0,0,114,116,0,0,0,70,114,136,0,0,0,41,7,
+ 114,4,0,0,0,114,127,0,0,0,114,128,0,0,0,218,
+ 23,115,112,101,99,95,102,114,111,109,95,102,105,108,101,95,
+ 108,111,99,97,116,105,111,110,114,116,0,0,0,114,80,0,
+ 0,0,114,113,0,0,0,41,6,114,17,0,0,0,114,110,
+ 0,0,0,114,114,0,0,0,114,116,0,0,0,114,137,0,
+ 0,0,90,6,115,101,97,114,99,104,114,10,0,0,0,114,
+ 10,0,0,0,114,11,0,0,0,114,92,0,0,0,159,1,
+ 0,0,115,36,0,0,0,0,2,10,1,8,1,4,1,6,
+ 2,8,1,12,1,12,1,6,1,2,255,6,3,8,1,10,
+ 1,2,1,14,1,12,1,12,3,4,2,114,92,0,0,0,
+ 99,3,0,0,0,0,0,0,0,0,0,0,0,8,0,0,
+ 0,8,0,0,0,67,0,0,0,115,42,1,0,0,122,10,
+ 124,0,106,0,125,3,87,0,110,18,4,0,116,1,121,28,
+ 1,0,1,0,1,0,89,0,110,14,48,0,124,3,100,0,
+ 117,1,114,42,124,3,83,0,124,0,106,2,125,4,124,1,
+ 100,0,117,0,114,86,122,10,124,0,106,3,125,1,87,0,
+ 110,18,4,0,116,1,121,84,1,0,1,0,1,0,89,0,
+ 110,2,48,0,122,10,124,0,106,4,125,5,87,0,110,22,
+ 4,0,116,1,121,118,1,0,1,0,1,0,100,0,125,5,
+ 89,0,110,2,48,0,124,2,100,0,117,0,114,176,124,5,
+ 100,0,117,0,114,172,122,10,124,1,106,5,125,2,87,0,
+ 113,176,4,0,116,1,121,168,1,0,1,0,1,0,100,0,
+ 125,2,89,0,113,176,48,0,110,4,124,5,125,2,122,10,
+ 124,0,106,6,125,6,87,0,110,22,4,0,116,1,121,208,
+ 1,0,1,0,1,0,100,0,125,6,89,0,110,2,48,0,
+ 122,14,116,7,124,0,106,8,131,1,125,7,87,0,110,22,
+ 4,0,116,1,121,246,1,0,1,0,1,0,100,0,125,7,
+ 89,0,110,2,48,0,116,9,124,4,124,1,124,2,100,1,
+ 141,3,125,3,124,5,100,0,117,0,144,1,114,20,100,2,
+ 110,2,100,3,124,3,95,10,124,6,124,3,95,11,124,7,
+ 124,3,95,12,124,3,83,0,41,4,78,169,1,114,114,0,
+ 0,0,70,84,41,13,114,106,0,0,0,114,107,0,0,0,
+ 114,1,0,0,0,114,99,0,0,0,114,109,0,0,0,218,
+ 7,95,79,82,73,71,73,78,218,10,95,95,99,97,99,104,
+ 101,100,95,95,218,4,108,105,115,116,218,8,95,95,112,97,
+ 116,104,95,95,114,113,0,0,0,114,118,0,0,0,114,123,
+ 0,0,0,114,117,0,0,0,41,8,114,97,0,0,0,114,
+ 110,0,0,0,114,114,0,0,0,114,96,0,0,0,114,17,
+ 0,0,0,90,8,108,111,99,97,116,105,111,110,114,123,0,
+ 0,0,114,117,0,0,0,114,10,0,0,0,114,10,0,0,
+ 0,114,11,0,0,0,218,17,95,115,112,101,99,95,102,114,
+ 111,109,95,109,111,100,117,108,101,185,1,0,0,115,72,0,
+ 0,0,0,2,2,1,10,1,12,1,6,2,8,1,4,2,
+ 6,1,8,1,2,1,10,1,12,2,6,1,2,1,10,1,
+ 12,1,10,1,8,1,8,1,2,1,10,1,12,1,12,2,
+ 4,1,2,1,10,1,12,1,10,1,2,1,14,1,12,1,
+ 10,2,14,1,20,1,6,1,6,1,114,143,0,0,0,70,
+ 169,1,218,8,111,118,101,114,114,105,100,101,99,2,0,0,
+ 0,0,0,0,0,1,0,0,0,5,0,0,0,8,0,0,
+ 0,67,0,0,0,115,210,1,0,0,124,2,115,20,116,0,
+ 124,1,100,1,100,0,131,3,100,0,117,0,114,52,122,12,
+ 124,0,106,1,124,1,95,2,87,0,110,18,4,0,116,3,
+ 121,50,1,0,1,0,1,0,89,0,110,2,48,0,124,2,
+ 115,72,116,0,124,1,100,2,100,0,131,3,100,0,117,0,
+ 114,174,124,0,106,4,125,3,124,3,100,0,117,0,114,144,
+ 124,0,106,5,100,0,117,1,114,144,116,6,100,0,117,0,
+ 114,108,116,7,130,1,116,6,106,8,125,4,124,4,160,9,
+ 124,4,161,1,125,3,124,0,106,5,124,3,95,10,124,3,
+ 124,0,95,4,100,0,124,1,95,11,122,10,124,3,124,1,
+ 95,12,87,0,110,18,4,0,116,3,121,172,1,0,1,0,
+ 1,0,89,0,110,2,48,0,124,2,115,194,116,0,124,1,
+ 100,3,100,0,131,3,100,0,117,0,114,226,122,12,124,0,
+ 106,13,124,1,95,14,87,0,110,18,4,0,116,3,121,224,
+ 1,0,1,0,1,0,89,0,110,2,48,0,122,10,124,0,
+ 124,1,95,15,87,0,110,18,4,0,116,3,121,254,1,0,
+ 1,0,1,0,89,0,110,2,48,0,124,2,144,1,115,24,
+ 116,0,124,1,100,4,100,0,131,3,100,0,117,0,144,1,
+ 114,70,124,0,106,5,100,0,117,1,144,1,114,70,122,12,
+ 124,0,106,5,124,1,95,16,87,0,110,20,4,0,116,3,
+ 144,1,121,68,1,0,1,0,1,0,89,0,110,2,48,0,
+ 124,0,106,17,144,1,114,206,124,2,144,1,115,102,116,0,
+ 124,1,100,5,100,0,131,3,100,0,117,0,144,1,114,136,
+ 122,12,124,0,106,18,124,1,95,11,87,0,110,20,4,0,
+ 116,3,144,1,121,134,1,0,1,0,1,0,89,0,110,2,
+ 48,0,124,2,144,1,115,160,116,0,124,1,100,6,100,0,
+ 131,3,100,0,117,0,144,1,114,206,124,0,106,19,100,0,
+ 117,1,144,1,114,206,122,12,124,0,106,19,124,1,95,20,
+ 87,0,110,20,4,0,116,3,144,1,121,204,1,0,1,0,
+ 1,0,89,0,110,2,48,0,124,1,83,0,41,7,78,114,
+ 1,0,0,0,114,99,0,0,0,218,11,95,95,112,97,99,
+ 107,97,103,101,95,95,114,142,0,0,0,114,109,0,0,0,
+ 114,140,0,0,0,41,21,114,6,0,0,0,114,17,0,0,
+ 0,114,1,0,0,0,114,107,0,0,0,114,110,0,0,0,
+ 114,117,0,0,0,114,127,0,0,0,114,128,0,0,0,218,
+ 16,95,78,97,109,101,115,112,97,99,101,76,111,97,100,101,
+ 114,218,7,95,95,110,101,119,95,95,90,5,95,112,97,116,
+ 104,114,109,0,0,0,114,99,0,0,0,114,131,0,0,0,
+ 114,146,0,0,0,114,106,0,0,0,114,142,0,0,0,114,
+ 124,0,0,0,114,114,0,0,0,114,123,0,0,0,114,140,
+ 0,0,0,41,5,114,96,0,0,0,114,97,0,0,0,114,
+ 145,0,0,0,114,110,0,0,0,114,147,0,0,0,114,10,
+ 0,0,0,114,10,0,0,0,114,11,0,0,0,218,18,95,
+ 105,110,105,116,95,109,111,100,117,108,101,95,97,116,116,114,
+ 115,230,1,0,0,115,96,0,0,0,0,4,20,1,2,1,
+ 12,1,12,1,6,2,20,1,6,1,8,2,10,1,8,1,
+ 4,1,6,2,10,1,8,1,6,11,6,1,2,1,10,1,
+ 12,1,6,2,20,1,2,1,12,1,12,1,6,2,2,1,
+ 10,1,12,1,6,2,24,1,12,1,2,1,12,1,14,1,
+ 6,2,8,1,24,1,2,1,12,1,14,1,6,2,24,1,
+ 12,1,2,1,12,1,14,1,6,1,114,149,0,0,0,99,
+ 1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,
+ 3,0,0,0,67,0,0,0,115,82,0,0,0,100,1,125,
+ 1,116,0,124,0,106,1,100,2,131,2,114,30,124,0,106,
+ 1,160,2,124,0,161,1,125,1,110,20,116,0,124,0,106,
+ 1,100,3,131,2,114,50,116,3,100,4,131,1,130,1,124,
+ 1,100,1,117,0,114,68,116,4,124,0,106,5,131,1,125,
+ 1,116,6,124,0,124,1,131,2,1,0,124,1,83,0,41,
+ 5,122,43,67,114,101,97,116,101,32,97,32,109,111,100,117,
+ 108,101,32,98,97,115,101,100,32,111,110,32,116,104,101,32,
+ 112,114,111,118,105,100,101,100,32,115,112,101,99,46,78,218,
+ 13,99,114,101,97,116,101,95,109,111,100,117,108,101,218,11,
+ 101,120,101,99,95,109,111,100,117,108,101,122,66,108,111,97,
+ 100,101,114,115,32,116,104,97,116,32,100,101,102,105,110,101,
+ 32,101,120,101,99,95,109,111,100,117,108,101,40,41,32,109,
+ 117,115,116,32,97,108,115,111,32,100,101,102,105,110,101,32,
+ 99,114,101,97,116,101,95,109,111,100,117,108,101,40,41,41,
+ 7,114,4,0,0,0,114,110,0,0,0,114,150,0,0,0,
+ 114,80,0,0,0,114,18,0,0,0,114,17,0,0,0,114,
+ 149,0,0,0,169,2,114,96,0,0,0,114,97,0,0,0,
+ 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,
+ 16,109,111,100,117,108,101,95,102,114,111,109,95,115,112,101,
+ 99,46,2,0,0,115,18,0,0,0,0,3,4,1,12,3,
+ 14,1,12,1,8,2,8,1,10,1,10,1,114,153,0,0,
+ 0,99,1,0,0,0,0,0,0,0,0,0,0,0,2,0,
+ 0,0,4,0,0,0,67,0,0,0,115,106,0,0,0,124,
+ 0,106,0,100,1,117,0,114,14,100,2,110,4,124,0,106,
+ 0,125,1,124,0,106,1,100,1,117,0,114,66,124,0,106,
+ 2,100,1,117,0,114,50,100,3,160,3,124,1,161,1,83,
+ 0,100,4,160,3,124,1,124,0,106,2,161,2,83,0,110,
+ 36,124,0,106,4,114,86,100,5,160,3,124,1,124,0,106,
+ 1,161,2,83,0,100,6,160,3,124,0,106,0,124,0,106,
+ 1,161,2,83,0,100,1,83,0,41,7,122,38,82,101,116,
+ 117,114,110,32,116,104,101,32,114,101,112,114,32,116,111,32,
+ 117,115,101,32,102,111,114,32,116,104,101,32,109,111,100,117,
+ 108,101,46,78,114,101,0,0,0,114,102,0,0,0,114,103,
+ 0,0,0,114,104,0,0,0,250,18,60,109,111,100,117,108,
+ 101,32,123,33,114,125,32,40,123,125,41,62,41,5,114,17,
+ 0,0,0,114,114,0,0,0,114,110,0,0,0,114,46,0,
+ 0,0,114,124,0,0,0,41,2,114,96,0,0,0,114,17,
+ 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,
+ 0,0,114,108,0,0,0,63,2,0,0,115,16,0,0,0,
+ 0,3,20,1,10,1,10,1,10,2,16,2,6,1,14,2,
+ 114,108,0,0,0,99,2,0,0,0,0,0,0,0,0,0,
+ 0,0,4,0,0,0,10,0,0,0,67,0,0,0,115,250,
+ 0,0,0,124,0,106,0,125,2,116,1,124,2,131,1,143,
+ 216,1,0,116,2,106,3,160,4,124,2,161,1,124,1,117,
+ 1,114,54,100,1,160,5,124,2,161,1,125,3,116,6,124,
+ 3,124,2,100,2,141,2,130,1,122,132,124,0,106,7,100,
+ 3,117,0,114,106,124,0,106,8,100,3,117,0,114,90,116,
+ 6,100,4,124,0,106,0,100,2,141,2,130,1,116,9,124,
+ 0,124,1,100,5,100,6,141,3,1,0,110,52,116,9,124,
+ 0,124,1,100,5,100,6,141,3,1,0,116,10,124,0,106,
+ 7,100,7,131,2,115,146,124,0,106,7,160,11,124,2,161,
+ 1,1,0,110,12,124,0,106,7,160,12,124,1,161,1,1,
+ 0,87,0,116,2,106,3,160,13,124,0,106,0,161,1,125,
+ 1,124,1,116,2,106,3,124,0,106,0,60,0,110,28,116,
+ 2,106,3,160,13,124,0,106,0,161,1,125,1,124,1,116,
+ 2,106,3,124,0,106,0,60,0,48,0,87,0,100,3,4,
+ 0,4,0,131,3,1,0,110,16,49,0,115,236,48,0,1,
+ 0,1,0,1,0,89,0,1,0,124,1,83,0,41,8,122,
+ 70,69,120,101,99,117,116,101,32,116,104,101,32,115,112,101,
+ 99,39,115,32,115,112,101,99,105,102,105,101,100,32,109,111,
+ 100,117,108,101,32,105,110,32,97,110,32,101,120,105,115,116,
+ 105,110,103,32,109,111,100,117,108,101,39,115,32,110,97,109,
+ 101,115,112,97,99,101,46,122,30,109,111,100,117,108,101,32,
+ 123,33,114,125,32,110,111,116,32,105,110,32,115,121,115,46,
+ 109,111,100,117,108,101,115,114,16,0,0,0,78,250,14,109,
+ 105,115,115,105,110,103,32,108,111,97,100,101,114,84,114,144,
+ 0,0,0,114,151,0,0,0,41,14,114,17,0,0,0,114,
+ 51,0,0,0,114,15,0,0,0,114,93,0,0,0,114,35,
+ 0,0,0,114,46,0,0,0,114,80,0,0,0,114,110,0,
+ 0,0,114,117,0,0,0,114,149,0,0,0,114,4,0,0,
+ 0,218,11,108,111,97,100,95,109,111,100,117,108,101,114,151,
+ 0,0,0,218,3,112,111,112,41,4,114,96,0,0,0,114,
+ 97,0,0,0,114,17,0,0,0,218,3,109,115,103,114,10,
+ 0,0,0,114,10,0,0,0,114,11,0,0,0,114,94,0,
+ 0,0,80,2,0,0,115,38,0,0,0,0,2,6,1,10,
+ 1,16,1,10,1,12,1,2,1,10,1,10,1,14,2,16,
+ 2,14,1,12,4,14,2,14,4,14,1,14,255,14,1,44,
+ 1,114,94,0,0,0,99,1,0,0,0,0,0,0,0,0,
+ 0,0,0,2,0,0,0,8,0,0,0,67,0,0,0,115,
+ 20,1,0,0,122,18,124,0,106,0,160,1,124,0,106,2,
+ 161,1,1,0,87,0,110,52,1,0,1,0,1,0,124,0,
+ 106,2,116,3,106,4,118,0,114,64,116,3,106,4,160,5,
+ 124,0,106,2,161,1,125,1,124,1,116,3,106,4,124,0,
+ 106,2,60,0,130,0,89,0,110,2,48,0,116,3,106,4,
+ 160,5,124,0,106,2,161,1,125,1,124,1,116,3,106,4,
+ 124,0,106,2,60,0,116,6,124,1,100,1,100,0,131,3,
+ 100,0,117,0,114,146,122,12,124,0,106,0,124,1,95,7,
+ 87,0,110,18,4,0,116,8,121,144,1,0,1,0,1,0,
+ 89,0,110,2,48,0,116,6,124,1,100,2,100,0,131,3,
+ 100,0,117,0,114,222,122,40,124,1,106,9,124,1,95,10,
+ 116,11,124,1,100,3,131,2,115,200,124,0,106,2,160,12,
+ 100,4,161,1,100,5,25,0,124,1,95,10,87,0,110,18,
+ 4,0,116,8,121,220,1,0,1,0,1,0,89,0,110,2,
+ 48,0,116,6,124,1,100,6,100,0,131,3,100,0,117,0,
+ 144,1,114,16,122,10,124,0,124,1,95,13,87,0,110,20,
+ 4,0,116,8,144,1,121,14,1,0,1,0,1,0,89,0,
+ 110,2,48,0,124,1,83,0,41,7,78,114,99,0,0,0,
+ 114,146,0,0,0,114,142,0,0,0,114,129,0,0,0,114,
+ 22,0,0,0,114,106,0,0,0,41,14,114,110,0,0,0,
+ 114,156,0,0,0,114,17,0,0,0,114,15,0,0,0,114,
+ 93,0,0,0,114,157,0,0,0,114,6,0,0,0,114,99,
+ 0,0,0,114,107,0,0,0,114,1,0,0,0,114,146,0,
+ 0,0,114,4,0,0,0,114,130,0,0,0,114,106,0,0,
+ 0,114,152,0,0,0,114,10,0,0,0,114,10,0,0,0,
+ 114,11,0,0,0,218,25,95,108,111,97,100,95,98,97,99,
+ 107,119,97,114,100,95,99,111,109,112,97,116,105,98,108,101,
+ 110,2,0,0,115,54,0,0,0,0,4,2,1,18,1,6,
+ 1,12,1,14,1,12,1,8,3,14,1,12,1,16,1,2,
+ 1,12,1,12,1,6,1,16,1,2,4,8,1,10,1,22,
+ 1,12,1,6,1,18,1,2,1,10,1,14,1,6,1,114,
+ 159,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,
+ 0,2,0,0,0,11,0,0,0,67,0,0,0,115,224,0,
+ 0,0,124,0,106,0,100,0,117,1,114,30,116,1,124,0,
+ 106,0,100,1,131,2,115,30,116,2,124,0,131,1,83,0,
+ 116,3,124,0,131,1,125,1,100,2,124,0,95,4,122,166,
+ 124,1,116,5,106,6,124,0,106,7,60,0,122,52,124,0,
+ 106,0,100,0,117,0,114,96,124,0,106,8,100,0,117,0,
+ 114,108,116,9,100,3,124,0,106,7,100,4,141,2,130,1,
+ 110,12,124,0,106,0,160,10,124,1,161,1,1,0,87,0,
+ 110,48,1,0,1,0,1,0,122,14,116,5,106,6,124,0,
+ 106,7,61,0,87,0,110,18,4,0,116,11,121,150,1,0,
+ 1,0,1,0,89,0,110,2,48,0,130,0,89,0,110,2,
+ 48,0,116,5,106,6,160,12,124,0,106,7,161,1,125,1,
+ 124,1,116,5,106,6,124,0,106,7,60,0,116,13,100,5,
+ 124,0,106,7,124,0,106,0,131,3,1,0,87,0,100,6,
+ 124,0,95,4,110,8,100,6,124,0,95,4,48,0,124,1,
+ 83,0,41,7,78,114,151,0,0,0,84,114,155,0,0,0,
+ 114,16,0,0,0,122,18,105,109,112,111,114,116,32,123,33,
+ 114,125,32,35,32,123,33,114,125,70,41,14,114,110,0,0,
+ 0,114,4,0,0,0,114,159,0,0,0,114,153,0,0,0,
+ 90,13,95,105,110,105,116,105,97,108,105,122,105,110,103,114,
+ 15,0,0,0,114,93,0,0,0,114,17,0,0,0,114,117,
+ 0,0,0,114,80,0,0,0,114,151,0,0,0,114,64,0,
+ 0,0,114,157,0,0,0,114,77,0,0,0,114,152,0,0,
+ 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
+ 218,14,95,108,111,97,100,95,117,110,108,111,99,107,101,100,
+ 147,2,0,0,115,46,0,0,0,0,2,10,2,12,1,8,
+ 2,8,5,6,1,2,1,12,1,2,1,10,1,10,1,16,
+ 3,16,1,6,1,2,1,14,1,12,1,6,1,8,5,14,
+ 1,12,1,18,2,16,2,114,160,0,0,0,99,1,0,0,
+ 0,0,0,0,0,0,0,0,0,1,0,0,0,8,0,0,
+ 0,67,0,0,0,115,54,0,0,0,116,0,124,0,106,1,
+ 131,1,143,24,1,0,116,2,124,0,131,1,87,0,2,0,
+ 100,1,4,0,4,0,131,3,1,0,83,0,49,0,115,40,
+ 48,0,1,0,1,0,1,0,89,0,1,0,100,1,83,0,
+ 41,2,122,191,82,101,116,117,114,110,32,97,32,110,101,119,
+ 32,109,111,100,117,108,101,32,111,98,106,101,99,116,44,32,
+ 108,111,97,100,101,100,32,98,121,32,116,104,101,32,115,112,
+ 101,99,39,115,32,108,111,97,100,101,114,46,10,10,32,32,
+ 32,32,84,104,101,32,109,111,100,117,108,101,32,105,115,32,
+ 110,111,116,32,97,100,100,101,100,32,116,111,32,105,116,115,
+ 32,112,97,114,101,110,116,46,10,10,32,32,32,32,73,102,
+ 32,97,32,109,111,100,117,108,101,32,105,115,32,97,108,114,
+ 101,97,100,121,32,105,110,32,115,121,115,46,109,111,100,117,
+ 108,101,115,44,32,116,104,97,116,32,101,120,105,115,116,105,
+ 110,103,32,109,111,100,117,108,101,32,103,101,116,115,10,32,
+ 32,32,32,99,108,111,98,98,101,114,101,100,46,10,10,32,
+ 32,32,32,78,41,3,114,51,0,0,0,114,17,0,0,0,
+ 114,160,0,0,0,41,1,114,96,0,0,0,114,10,0,0,
+ 0,114,10,0,0,0,114,11,0,0,0,114,95,0,0,0,
+ 189,2,0,0,115,4,0,0,0,0,9,12,1,114,95,0,
+ 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,4,0,0,0,64,0,0,0,115,140,0,0,0,
+ 101,0,90,1,100,0,90,2,100,1,90,3,100,2,90,4,
+ 101,5,100,3,100,4,132,0,131,1,90,6,101,7,100,20,
+ 100,6,100,7,132,1,131,1,90,8,101,7,100,21,100,8,
+ 100,9,132,1,131,1,90,9,101,7,100,10,100,11,132,0,
+ 131,1,90,10,101,7,100,12,100,13,132,0,131,1,90,11,
+ 101,7,101,12,100,14,100,15,132,0,131,1,131,1,90,13,
+ 101,7,101,12,100,16,100,17,132,0,131,1,131,1,90,14,
+ 101,7,101,12,100,18,100,19,132,0,131,1,131,1,90,15,
+ 101,7,101,16,131,1,90,17,100,5,83,0,41,22,218,15,
+ 66,117,105,108,116,105,110,73,109,112,111,114,116,101,114,122,
+ 144,77,101,116,97,32,112,97,116,104,32,105,109,112,111,114,
+ 116,32,102,111,114,32,98,117,105,108,116,45,105,110,32,109,
+ 111,100,117,108,101,115,46,10,10,32,32,32,32,65,108,108,
+ 32,109,101,116,104,111,100,115,32,97,114,101,32,101,105,116,
+ 104,101,114,32,99,108,97,115,115,32,111,114,32,115,116,97,
+ 116,105,99,32,109,101,116,104,111,100,115,32,116,111,32,97,
+ 118,111,105,100,32,116,104,101,32,110,101,101,100,32,116,111,
+ 10,32,32,32,32,105,110,115,116,97,110,116,105,97,116,101,
+ 32,116,104,101,32,99,108,97,115,115,46,10,10,32,32,32,
+ 32,122,8,98,117,105,108,116,45,105,110,99,1,0,0,0,
+ 0,0,0,0,0,0,0,0,1,0,0,0,5,0,0,0,
+ 67,0,0,0,115,22,0,0,0,100,1,124,0,106,0,155,
+ 2,100,2,116,1,106,2,155,0,100,3,157,5,83,0,41,
+ 4,250,115,82,101,116,117,114,110,32,114,101,112,114,32,102,
+ 111,114,32,116,104,101,32,109,111,100,117,108,101,46,10,10,
+ 32,32,32,32,32,32,32,32,84,104,101,32,109,101,116,104,
+ 111,100,32,105,115,32,100,101,112,114,101,99,97,116,101,100,
+ 46,32,32,84,104,101,32,105,109,112,111,114,116,32,109,97,
+ 99,104,105,110,101,114,121,32,100,111,101,115,32,116,104,101,
+ 32,106,111,98,32,105,116,115,101,108,102,46,10,10,32,32,
+ 32,32,32,32,32,32,122,8,60,109,111,100,117,108,101,32,
+ 122,2,32,40,122,2,41,62,41,3,114,1,0,0,0,114,
+ 161,0,0,0,114,139,0,0,0,41,1,114,97,0,0,0,
+ 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,
+ 100,0,0,0,215,2,0,0,115,2,0,0,0,0,7,122,
+ 27,66,117,105,108,116,105,110,73,109,112,111,114,116,101,114,
+ 46,109,111,100,117,108,101,95,114,101,112,114,78,99,4,0,
+ 0,0,0,0,0,0,0,0,0,0,4,0,0,0,5,0,
+ 0,0,67,0,0,0,115,46,0,0,0,124,2,100,0,117,
+ 1,114,12,100,0,83,0,116,0,160,1,124,1,161,1,114,
+ 38,116,2,124,1,124,0,124,0,106,3,100,1,141,3,83,
+ 0,100,0,83,0,100,0,83,0,169,2,78,114,138,0,0,
+ 0,41,4,114,58,0,0,0,90,10,105,115,95,98,117,105,
+ 108,116,105,110,114,92,0,0,0,114,139,0,0,0,169,4,
+ 218,3,99,108,115,114,82,0,0,0,218,4,112,97,116,104,
+ 218,6,116,97,114,103,101,116,114,10,0,0,0,114,10,0,
+ 0,0,114,11,0,0,0,218,9,102,105,110,100,95,115,112,
+ 101,99,224,2,0,0,115,10,0,0,0,0,2,8,1,4,
+ 1,10,1,16,2,122,25,66,117,105,108,116,105,110,73,109,
+ 112,111,114,116,101,114,46,102,105,110,100,95,115,112,101,99,
+ 99,3,0,0,0,0,0,0,0,0,0,0,0,4,0,0,
+ 0,4,0,0,0,67,0,0,0,115,30,0,0,0,124,0,
+ 160,0,124,1,124,2,161,2,125,3,124,3,100,1,117,1,
+ 114,26,124,3,106,1,83,0,100,1,83,0,41,2,122,175,
+ 70,105,110,100,32,116,104,101,32,98,117,105,108,116,45,105,
+ 110,32,109,111,100,117,108,101,46,10,10,32,32,32,32,32,
+ 32,32,32,73,102,32,39,112,97,116,104,39,32,105,115,32,
+ 101,118,101,114,32,115,112,101,99,105,102,105,101,100,32,116,
+ 104,101,110,32,116,104,101,32,115,101,97,114,99,104,32,105,
+ 115,32,99,111,110,115,105,100,101,114,101,100,32,97,32,102,
+ 97,105,108,117,114,101,46,10,10,32,32,32,32,32,32,32,
+ 32,84,104,105,115,32,109,101,116,104,111,100,32,105,115,32,
+ 100,101,112,114,101,99,97,116,101,100,46,32,32,85,115,101,
+ 32,102,105,110,100,95,115,112,101,99,40,41,32,105,110,115,
+ 116,101,97,100,46,10,10,32,32,32,32,32,32,32,32,78,
+ 41,2,114,168,0,0,0,114,110,0,0,0,41,4,114,165,
+ 0,0,0,114,82,0,0,0,114,166,0,0,0,114,96,0,
+ 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+ 0,218,11,102,105,110,100,95,109,111,100,117,108,101,233,2,
+ 0,0,115,4,0,0,0,0,9,12,1,122,27,66,117,105,
+ 108,116,105,110,73,109,112,111,114,116,101,114,46,102,105,110,
+ 100,95,109,111,100,117,108,101,99,2,0,0,0,0,0,0,
+ 0,0,0,0,0,2,0,0,0,4,0,0,0,67,0,0,
+ 0,115,46,0,0,0,124,1,106,0,116,1,106,2,118,1,
+ 114,34,116,3,100,1,160,4,124,1,106,0,161,1,124,1,
+ 106,0,100,2,141,2,130,1,116,5,116,6,106,7,124,1,
+ 131,2,83,0,41,3,122,24,67,114,101,97,116,101,32,97,
+ 32,98,117,105,108,116,45,105,110,32,109,111,100,117,108,101,
+ 114,78,0,0,0,114,16,0,0,0,41,8,114,17,0,0,
+ 0,114,15,0,0,0,114,79,0,0,0,114,80,0,0,0,
+ 114,46,0,0,0,114,68,0,0,0,114,58,0,0,0,90,
+ 14,99,114,101,97,116,101,95,98,117,105,108,116,105,110,41,
+ 2,114,30,0,0,0,114,96,0,0,0,114,10,0,0,0,
+ 114,10,0,0,0,114,11,0,0,0,114,150,0,0,0,245,
+ 2,0,0,115,10,0,0,0,0,3,12,1,12,1,4,255,
+ 6,2,122,29,66,117,105,108,116,105,110,73,109,112,111,114,
+ 116,101,114,46,99,114,101,97,116,101,95,109,111,100,117,108,
+ 101,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,
+ 0,0,3,0,0,0,67,0,0,0,115,16,0,0,0,116,
+ 0,116,1,106,2,124,1,131,2,1,0,100,1,83,0,41,
+ 2,122,22,69,120,101,99,32,97,32,98,117,105,108,116,45,
+ 105,110,32,109,111,100,117,108,101,78,41,3,114,68,0,0,
+ 0,114,58,0,0,0,90,12,101,120,101,99,95,98,117,105,
+ 108,116,105,110,41,2,114,30,0,0,0,114,97,0,0,0,
+ 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,
+ 151,0,0,0,253,2,0,0,115,2,0,0,0,0,3,122,
+ 27,66,117,105,108,116,105,110,73,109,112,111,114,116,101,114,
+ 46,101,120,101,99,95,109,111,100,117,108,101,99,2,0,0,
+ 0,0,0,0,0,0,0,0,0,2,0,0,0,1,0,0,
+ 0,67,0,0,0,115,4,0,0,0,100,1,83,0,41,2,
+ 122,57,82,101,116,117,114,110,32,78,111,110,101,32,97,115,
+ 32,98,117,105,108,116,45,105,110,32,109,111,100,117,108,101,
+ 115,32,100,111,32,110,111,116,32,104,97,118,101,32,99,111,
+ 100,101,32,111,98,106,101,99,116,115,46,78,114,10,0,0,
+ 0,169,2,114,165,0,0,0,114,82,0,0,0,114,10,0,
+ 0,0,114,10,0,0,0,114,11,0,0,0,218,8,103,101,
+ 116,95,99,111,100,101,2,3,0,0,115,2,0,0,0,0,
+ 4,122,24,66,117,105,108,116,105,110,73,109,112,111,114,116,
+ 101,114,46,103,101,116,95,99,111,100,101,99,2,0,0,0,
+ 0,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,
+ 67,0,0,0,115,4,0,0,0,100,1,83,0,41,2,122,
+ 56,82,101,116,117,114,110,32,78,111,110,101,32,97,115,32,
+ 98,117,105,108,116,45,105,110,32,109,111,100,117,108,101,115,
+ 32,100,111,32,110,111,116,32,104,97,118,101,32,115,111,117,
+ 114,99,101,32,99,111,100,101,46,78,114,10,0,0,0,114,
+ 170,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,
+ 0,0,0,218,10,103,101,116,95,115,111,117,114,99,101,8,
+ 3,0,0,115,2,0,0,0,0,4,122,26,66,117,105,108,
+ 116,105,110,73,109,112,111,114,116,101,114,46,103,101,116,95,
+ 115,111,117,114,99,101,99,2,0,0,0,0,0,0,0,0,
+ 0,0,0,2,0,0,0,1,0,0,0,67,0,0,0,115,
+ 4,0,0,0,100,1,83,0,41,2,122,52,82,101,116,117,
+ 114,110,32,70,97,108,115,101,32,97,115,32,98,117,105,108,
+ 116,45,105,110,32,109,111,100,117,108,101,115,32,97,114,101,
+ 32,110,101,118,101,114,32,112,97,99,107,97,103,101,115,46,
+ 70,114,10,0,0,0,114,170,0,0,0,114,10,0,0,0,
+ 114,10,0,0,0,114,11,0,0,0,114,116,0,0,0,14,
+ 3,0,0,115,2,0,0,0,0,4,122,26,66,117,105,108,
+ 116,105,110,73,109,112,111,114,116,101,114,46,105,115,95,112,
+ 97,99,107,97,103,101,41,2,78,78,41,1,78,41,18,114,
+ 1,0,0,0,114,0,0,0,0,114,2,0,0,0,114,3,
+ 0,0,0,114,139,0,0,0,218,12,115,116,97,116,105,99,
+ 109,101,116,104,111,100,114,100,0,0,0,218,11,99,108,97,
+ 115,115,109,101,116,104,111,100,114,168,0,0,0,114,169,0,
+ 0,0,114,150,0,0,0,114,151,0,0,0,114,87,0,0,
+ 0,114,171,0,0,0,114,172,0,0,0,114,116,0,0,0,
+ 114,98,0,0,0,114,156,0,0,0,114,10,0,0,0,114,
+ 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,161,
+ 0,0,0,204,2,0,0,115,44,0,0,0,8,2,4,7,
+ 4,2,2,1,10,8,2,1,12,8,2,1,12,11,2,1,
+ 10,7,2,1,10,4,2,1,2,1,12,4,2,1,2,1,
+ 12,4,2,1,2,1,12,4,114,161,0,0,0,99,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,
+ 0,0,64,0,0,0,115,144,0,0,0,101,0,90,1,100,
+ 0,90,2,100,1,90,3,100,2,90,4,101,5,100,3,100,
+ 4,132,0,131,1,90,6,101,7,100,22,100,6,100,7,132,
+ 1,131,1,90,8,101,7,100,23,100,8,100,9,132,1,131,
+ 1,90,9,101,7,100,10,100,11,132,0,131,1,90,10,101,
+ 5,100,12,100,13,132,0,131,1,90,11,101,7,100,14,100,
+ 15,132,0,131,1,90,12,101,7,101,13,100,16,100,17,132,
+ 0,131,1,131,1,90,14,101,7,101,13,100,18,100,19,132,
+ 0,131,1,131,1,90,15,101,7,101,13,100,20,100,21,132,
+ 0,131,1,131,1,90,16,100,5,83,0,41,24,218,14,70,
+ 114,111,122,101,110,73,109,112,111,114,116,101,114,122,142,77,
+ 101,116,97,32,112,97,116,104,32,105,109,112,111,114,116,32,
+ 102,111,114,32,102,114,111,122,101,110,32,109,111,100,117,108,
+ 101,115,46,10,10,32,32,32,32,65,108,108,32,109,101,116,
+ 104,111,100,115,32,97,114,101,32,101,105,116,104,101,114,32,
+ 99,108,97,115,115,32,111,114,32,115,116,97,116,105,99,32,
+ 109,101,116,104,111,100,115,32,116,111,32,97,118,111,105,100,
+ 32,116,104,101,32,110,101,101,100,32,116,111,10,32,32,32,
+ 32,105,110,115,116,97,110,116,105,97,116,101,32,116,104,101,
+ 32,99,108,97,115,115,46,10,10,32,32,32,32,90,6,102,
+ 114,111,122,101,110,99,1,0,0,0,0,0,0,0,0,0,
+ 0,0,1,0,0,0,4,0,0,0,67,0,0,0,115,16,
+ 0,0,0,100,1,160,0,124,0,106,1,116,2,106,3,161,
+ 2,83,0,41,2,114,162,0,0,0,114,154,0,0,0,41,
+ 4,114,46,0,0,0,114,1,0,0,0,114,175,0,0,0,
+ 114,139,0,0,0,41,1,218,1,109,114,10,0,0,0,114,
+ 10,0,0,0,114,11,0,0,0,114,100,0,0,0,34,3,
+ 0,0,115,2,0,0,0,0,7,122,26,70,114,111,122,101,
+ 110,73,109,112,111,114,116,101,114,46,109,111,100,117,108,101,
+ 95,114,101,112,114,78,99,4,0,0,0,0,0,0,0,0,
+ 0,0,0,4,0,0,0,5,0,0,0,67,0,0,0,115,
+ 34,0,0,0,116,0,160,1,124,1,161,1,114,26,116,2,
+ 124,1,124,0,124,0,106,3,100,1,141,3,83,0,100,0,
+ 83,0,100,0,83,0,114,163,0,0,0,41,4,114,58,0,
+ 0,0,114,89,0,0,0,114,92,0,0,0,114,139,0,0,
+ 0,114,164,0,0,0,114,10,0,0,0,114,10,0,0,0,
+ 114,11,0,0,0,114,168,0,0,0,43,3,0,0,115,6,
+ 0,0,0,0,2,10,1,16,2,122,24,70,114,111,122,101,
+ 110,73,109,112,111,114,116,101,114,46,102,105,110,100,95,115,
+ 112,101,99,99,3,0,0,0,0,0,0,0,0,0,0,0,
+ 3,0,0,0,3,0,0,0,67,0,0,0,115,18,0,0,
+ 0,116,0,160,1,124,1,161,1,114,14,124,0,83,0,100,
+ 1,83,0,41,2,122,93,70,105,110,100,32,97,32,102,114,
+ 111,122,101,110,32,109,111,100,117,108,101,46,10,10,32,32,
+ 32,32,32,32,32,32,84,104,105,115,32,109,101,116,104,111,
+ 100,32,105,115,32,100,101,112,114,101,99,97,116,101,100,46,
+ 32,32,85,115,101,32,102,105,110,100,95,115,112,101,99,40,
+ 41,32,105,110,115,116,101,97,100,46,10,10,32,32,32,32,
+ 32,32,32,32,78,41,2,114,58,0,0,0,114,89,0,0,
+ 0,41,3,114,165,0,0,0,114,82,0,0,0,114,166,0,
+ 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+ 0,114,169,0,0,0,50,3,0,0,115,2,0,0,0,0,
+ 7,122,26,70,114,111,122,101,110,73,109,112,111,114,116,101,
+ 114,46,102,105,110,100,95,109,111,100,117,108,101,99,2,0,
+ 0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,0,
+ 0,0,67,0,0,0,115,4,0,0,0,100,1,83,0,41,
+ 2,122,42,85,115,101,32,100,101,102,97,117,108,116,32,115,
+ 101,109,97,110,116,105,99,115,32,102,111,114,32,109,111,100,
+ 117,108,101,32,99,114,101,97,116,105,111,110,46,78,114,10,
+ 0,0,0,41,2,114,165,0,0,0,114,96,0,0,0,114,
+ 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,150,
+ 0,0,0,59,3,0,0,115,2,0,0,0,0,2,122,28,
+ 70,114,111,122,101,110,73,109,112,111,114,116,101,114,46,99,
+ 114,101,97,116,101,95,109,111,100,117,108,101,99,1,0,0,
+ 0,0,0,0,0,0,0,0,0,3,0,0,0,4,0,0,
+ 0,67,0,0,0,115,64,0,0,0,124,0,106,0,106,1,
+ 125,1,116,2,160,3,124,1,161,1,115,36,116,4,100,1,
+ 160,5,124,1,161,1,124,1,100,2,141,2,130,1,116,6,
+ 116,2,106,7,124,1,131,2,125,2,116,8,124,2,124,0,
+ 106,9,131,2,1,0,100,0,83,0,114,88,0,0,0,41,
+ 10,114,106,0,0,0,114,17,0,0,0,114,58,0,0,0,
+ 114,89,0,0,0,114,80,0,0,0,114,46,0,0,0,114,
+ 68,0,0,0,218,17,103,101,116,95,102,114,111,122,101,110,
+ 95,111,98,106,101,99,116,218,4,101,120,101,99,114,7,0,
+ 0,0,41,3,114,97,0,0,0,114,17,0,0,0,218,4,
+ 99,111,100,101,114,10,0,0,0,114,10,0,0,0,114,11,
+ 0,0,0,114,151,0,0,0,63,3,0,0,115,14,0,0,
+ 0,0,2,8,1,10,1,10,1,2,255,6,2,12,1,122,
+ 26,70,114,111,122,101,110,73,109,112,111,114,116,101,114,46,
+ 101,120,101,99,95,109,111,100,117,108,101,99,2,0,0,0,
+ 0,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,
+ 67,0,0,0,115,10,0,0,0,116,0,124,0,124,1,131,
+ 2,83,0,41,1,122,95,76,111,97,100,32,97,32,102,114,
+ 111,122,101,110,32,109,111,100,117,108,101,46,10,10,32,32,
+ 32,32,32,32,32,32,84,104,105,115,32,109,101,116,104,111,
+ 100,32,105,115,32,100,101,112,114,101,99,97,116,101,100,46,
+ 32,32,85,115,101,32,101,120,101,99,95,109,111,100,117,108,
+ 101,40,41,32,105,110,115,116,101,97,100,46,10,10,32,32,
+ 32,32,32,32,32,32,41,1,114,98,0,0,0,114,170,0,
+ 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+ 0,114,156,0,0,0,72,3,0,0,115,2,0,0,0,0,
+ 7,122,26,70,114,111,122,101,110,73,109,112,111,114,116,101,
+ 114,46,108,111,97,100,95,109,111,100,117,108,101,99,2,0,
+ 0,0,0,0,0,0,0,0,0,0,2,0,0,0,3,0,
+ 0,0,67,0,0,0,115,10,0,0,0,116,0,160,1,124,
+ 1,161,1,83,0,41,1,122,45,82,101,116,117,114,110,32,
+ 116,104,101,32,99,111,100,101,32,111,98,106,101,99,116,32,
+ 102,111,114,32,116,104,101,32,102,114,111,122,101,110,32,109,
+ 111,100,117,108,101,46,41,2,114,58,0,0,0,114,177,0,
+ 0,0,114,170,0,0,0,114,10,0,0,0,114,10,0,0,
+ 0,114,11,0,0,0,114,171,0,0,0,81,3,0,0,115,
+ 2,0,0,0,0,4,122,23,70,114,111,122,101,110,73,109,
+ 112,111,114,116,101,114,46,103,101,116,95,99,111,100,101,99,
+ 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,
+ 1,0,0,0,67,0,0,0,115,4,0,0,0,100,1,83,
+ 0,41,2,122,54,82,101,116,117,114,110,32,78,111,110,101,
+ 32,97,115,32,102,114,111,122,101,110,32,109,111,100,117,108,
+ 101,115,32,100,111,32,110,111,116,32,104,97,118,101,32,115,
+ 111,117,114,99,101,32,99,111,100,101,46,78,114,10,0,0,
+ 0,114,170,0,0,0,114,10,0,0,0,114,10,0,0,0,
+ 114,11,0,0,0,114,172,0,0,0,87,3,0,0,115,2,
+ 0,0,0,0,4,122,25,70,114,111,122,101,110,73,109,112,
+ 111,114,116,101,114,46,103,101,116,95,115,111,117,114,99,101,
+ 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,
+ 0,3,0,0,0,67,0,0,0,115,10,0,0,0,116,0,
+ 160,1,124,1,161,1,83,0,41,1,122,46,82,101,116,117,
+ 114,110,32,84,114,117,101,32,105,102,32,116,104,101,32,102,
+ 114,111,122,101,110,32,109,111,100,117,108,101,32,105,115,32,
+ 97,32,112,97,99,107,97,103,101,46,41,2,114,58,0,0,
+ 0,90,17,105,115,95,102,114,111,122,101,110,95,112,97,99,
+ 107,97,103,101,114,170,0,0,0,114,10,0,0,0,114,10,
+ 0,0,0,114,11,0,0,0,114,116,0,0,0,93,3,0,
+ 0,115,2,0,0,0,0,4,122,25,70,114,111,122,101,110,
+ 73,109,112,111,114,116,101,114,46,105,115,95,112,97,99,107,
+ 97,103,101,41,2,78,78,41,1,78,41,17,114,1,0,0,
+ 0,114,0,0,0,0,114,2,0,0,0,114,3,0,0,0,
+ 114,139,0,0,0,114,173,0,0,0,114,100,0,0,0,114,
+ 174,0,0,0,114,168,0,0,0,114,169,0,0,0,114,150,
+ 0,0,0,114,151,0,0,0,114,156,0,0,0,114,91,0,
+ 0,0,114,171,0,0,0,114,172,0,0,0,114,116,0,0,
+ 0,114,10,0,0,0,114,10,0,0,0,114,10,0,0,0,
+ 114,11,0,0,0,114,175,0,0,0,23,3,0,0,115,46,
+ 0,0,0,8,2,4,7,4,2,2,1,10,8,2,1,12,
+ 6,2,1,12,8,2,1,10,3,2,1,10,8,2,1,10,
+ 8,2,1,2,1,12,4,2,1,2,1,12,4,2,1,2,
+ 1,114,175,0,0,0,99,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,2,0,0,0,64,0,0,0,115,
+ 32,0,0,0,101,0,90,1,100,0,90,2,100,1,90,3,
+ 100,2,100,3,132,0,90,4,100,4,100,5,132,0,90,5,
+ 100,6,83,0,41,7,218,18,95,73,109,112,111,114,116,76,
+ 111,99,107,67,111,110,116,101,120,116,122,36,67,111,110,116,
+ 101,120,116,32,109,97,110,97,103,101,114,32,102,111,114,32,
+ 116,104,101,32,105,109,112,111,114,116,32,108,111,99,107,46,
+ 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
+ 0,2,0,0,0,67,0,0,0,115,12,0,0,0,116,0,
+ 160,1,161,0,1,0,100,1,83,0,41,2,122,24,65,99,
+ 113,117,105,114,101,32,116,104,101,32,105,109,112,111,114,116,
+ 32,108,111,99,107,46,78,41,2,114,58,0,0,0,114,59,
+ 0,0,0,114,48,0,0,0,114,10,0,0,0,114,10,0,
+ 0,0,114,11,0,0,0,114,55,0,0,0,106,3,0,0,
+ 115,2,0,0,0,0,2,122,28,95,73,109,112,111,114,116,
+ 76,111,99,107,67,111,110,116,101,120,116,46,95,95,101,110,
+ 116,101,114,95,95,99,4,0,0,0,0,0,0,0,0,0,
+ 0,0,4,0,0,0,2,0,0,0,67,0,0,0,115,12,
+ 0,0,0,116,0,160,1,161,0,1,0,100,1,83,0,41,
+ 2,122,60,82,101,108,101,97,115,101,32,116,104,101,32,105,
+ 109,112,111,114,116,32,108,111,99,107,32,114,101,103,97,114,
+ 100,108,101,115,115,32,111,102,32,97,110,121,32,114,97,105,
+ 115,101,100,32,101,120,99,101,112,116,105,111,110,115,46,78,
+ 41,2,114,58,0,0,0,114,61,0,0,0,41,4,114,30,
+ 0,0,0,218,8,101,120,99,95,116,121,112,101,218,9,101,
+ 120,99,95,118,97,108,117,101,218,13,101,120,99,95,116,114,
+ 97,99,101,98,97,99,107,114,10,0,0,0,114,10,0,0,
+ 0,114,11,0,0,0,114,57,0,0,0,110,3,0,0,115,
+ 2,0,0,0,0,2,122,27,95,73,109,112,111,114,116,76,
+ 111,99,107,67,111,110,116,101,120,116,46,95,95,101,120,105,
+ 116,95,95,78,41,6,114,1,0,0,0,114,0,0,0,0,
+ 114,2,0,0,0,114,3,0,0,0,114,55,0,0,0,114,
+ 57,0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,
+ 0,0,0,114,11,0,0,0,114,180,0,0,0,102,3,0,
+ 0,115,6,0,0,0,8,2,4,2,8,4,114,180,0,0,
+ 0,99,3,0,0,0,0,0,0,0,0,0,0,0,5,0,
+ 0,0,5,0,0,0,67,0,0,0,115,64,0,0,0,124,
+ 1,160,0,100,1,124,2,100,2,24,0,161,2,125,3,116,
+ 1,124,3,131,1,124,2,107,0,114,36,116,2,100,3,131,
+ 1,130,1,124,3,100,4,25,0,125,4,124,0,114,60,100,
+ 5,160,3,124,4,124,0,161,2,83,0,124,4,83,0,41,
+ 6,122,50,82,101,115,111,108,118,101,32,97,32,114,101,108,
+ 97,116,105,118,101,32,109,111,100,117,108,101,32,110,97,109,
+ 101,32,116,111,32,97,110,32,97,98,115,111,108,117,116,101,
+ 32,111,110,101,46,114,129,0,0,0,114,39,0,0,0,122,
+ 50,97,116,116,101,109,112,116,101,100,32,114,101,108,97,116,
+ 105,118,101,32,105,109,112,111,114,116,32,98,101,121,111,110,
+ 100,32,116,111,112,45,108,101,118,101,108,32,112,97,99,107,
+ 97,103,101,114,22,0,0,0,250,5,123,125,46,123,125,41,
+ 4,218,6,114,115,112,108,105,116,218,3,108,101,110,114,80,
+ 0,0,0,114,46,0,0,0,41,5,114,17,0,0,0,218,
+ 7,112,97,99,107,97,103,101,218,5,108,101,118,101,108,90,
+ 4,98,105,116,115,90,4,98,97,115,101,114,10,0,0,0,
+ 114,10,0,0,0,114,11,0,0,0,218,13,95,114,101,115,
+ 111,108,118,101,95,110,97,109,101,115,3,0,0,115,10,0,
+ 0,0,0,2,16,1,12,1,8,1,8,1,114,189,0,0,
+ 0,99,3,0,0,0,0,0,0,0,0,0,0,0,4,0,
+ 0,0,4,0,0,0,67,0,0,0,115,34,0,0,0,124,
+ 0,160,0,124,1,124,2,161,2,125,3,124,3,100,0,117,
+ 0,114,24,100,0,83,0,116,1,124,1,124,3,131,2,83,
+ 0,114,13,0,0,0,41,2,114,169,0,0,0,114,92,0,
+ 0,0,41,4,218,6,102,105,110,100,101,114,114,17,0,0,
+ 0,114,166,0,0,0,114,110,0,0,0,114,10,0,0,0,
+ 114,10,0,0,0,114,11,0,0,0,218,17,95,102,105,110,
+ 100,95,115,112,101,99,95,108,101,103,97,99,121,124,3,0,
+ 0,115,8,0,0,0,0,3,12,1,8,1,4,1,114,191,
+ 0,0,0,99,3,0,0,0,0,0,0,0,0,0,0,0,
+ 10,0,0,0,10,0,0,0,67,0,0,0,115,32,1,0,
+ 0,116,0,106,1,125,3,124,3,100,1,117,0,114,22,116,
+ 2,100,2,131,1,130,1,124,3,115,38,116,3,160,4,100,
+ 3,116,5,161,2,1,0,124,0,116,0,106,6,118,0,125,
+ 4,124,3,68,0,93,230,125,5,116,7,131,0,143,94,1,
+ 0,122,10,124,5,106,8,125,6,87,0,110,54,4,0,116,
+ 9,121,128,1,0,1,0,1,0,116,10,124,5,124,0,124,
+ 1,131,3,125,7,124,7,100,1,117,0,114,124,89,0,87,
+ 0,100,1,4,0,4,0,131,3,1,0,113,52,89,0,110,
+ 14,48,0,124,6,124,0,124,1,124,2,131,3,125,7,87,
+ 0,100,1,4,0,4,0,131,3,1,0,110,16,49,0,115,
+ 162,48,0,1,0,1,0,1,0,89,0,1,0,124,7,100,
+ 1,117,1,114,52,124,4,144,1,115,18,124,0,116,0,106,
+ 6,118,0,144,1,114,18,116,0,106,6,124,0,25,0,125,
+ 8,122,10,124,8,106,11,125,9,87,0,110,26,4,0,116,
+ 9,121,244,1,0,1,0,1,0,124,7,6,0,89,0,2,
+ 0,1,0,83,0,48,0,124,9,100,1,117,0,144,1,114,
+ 8,124,7,2,0,1,0,83,0,124,9,2,0,1,0,83,
+ 0,113,52,124,7,2,0,1,0,83,0,113,52,100,1,83,
+ 0,41,4,122,21,70,105,110,100,32,97,32,109,111,100,117,
+ 108,101,39,115,32,115,112,101,99,46,78,122,53,115,121,115,
+ 46,109,101,116,97,95,112,97,116,104,32,105,115,32,78,111,
+ 110,101,44,32,80,121,116,104,111,110,32,105,115,32,108,105,
+ 107,101,108,121,32,115,104,117,116,116,105,110,103,32,100,111,
+ 119,110,122,22,115,121,115,46,109,101,116,97,95,112,97,116,
+ 104,32,105,115,32,101,109,112,116,121,41,12,114,15,0,0,
+ 0,218,9,109,101,116,97,95,112,97,116,104,114,80,0,0,
+ 0,218,9,95,119,97,114,110,105,110,103,115,218,4,119,97,
+ 114,110,218,13,73,109,112,111,114,116,87,97,114,110,105,110,
+ 103,114,93,0,0,0,114,180,0,0,0,114,168,0,0,0,
+ 114,107,0,0,0,114,191,0,0,0,114,106,0,0,0,41,
+ 10,114,17,0,0,0,114,166,0,0,0,114,167,0,0,0,
+ 114,192,0,0,0,90,9,105,115,95,114,101,108,111,97,100,
+ 114,190,0,0,0,114,168,0,0,0,114,96,0,0,0,114,
+ 97,0,0,0,114,106,0,0,0,114,10,0,0,0,114,10,
+ 0,0,0,114,11,0,0,0,218,10,95,102,105,110,100,95,
+ 115,112,101,99,133,3,0,0,115,54,0,0,0,0,2,6,
+ 1,8,2,8,3,4,1,12,5,10,1,8,1,8,1,2,
+ 1,10,1,12,1,12,1,8,1,22,2,42,1,8,2,18,
+ 1,10,1,2,1,10,1,12,4,14,2,10,1,8,2,10,
+ 2,10,2,114,196,0,0,0,99,3,0,0,0,0,0,0,
+ 0,0,0,0,0,3,0,0,0,5,0,0,0,67,0,0,
+ 0,115,108,0,0,0,116,0,124,0,116,1,131,2,115,28,
+ 116,2,100,1,160,3,116,4,124,0,131,1,161,1,131,1,
+ 130,1,124,2,100,2,107,0,114,44,116,5,100,3,131,1,
+ 130,1,124,2,100,2,107,4,114,84,116,0,124,1,116,1,
+ 131,2,115,72,116,2,100,4,131,1,130,1,110,12,124,1,
+ 115,84,116,6,100,5,131,1,130,1,124,0,115,104,124,2,
+ 100,2,107,2,114,104,116,5,100,6,131,1,130,1,100,7,
+ 83,0,41,8,122,28,86,101,114,105,102,121,32,97,114,103,
+ 117,109,101,110,116,115,32,97,114,101,32,34,115,97,110,101,
+ 34,46,122,31,109,111,100,117,108,101,32,110,97,109,101,32,
+ 109,117,115,116,32,98,101,32,115,116,114,44,32,110,111,116,
+ 32,123,125,114,22,0,0,0,122,18,108,101,118,101,108,32,
+ 109,117,115,116,32,98,101,32,62,61,32,48,122,31,95,95,
+ 112,97,99,107,97,103,101,95,95,32,110,111,116,32,115,101,
+ 116,32,116,111,32,97,32,115,116,114,105,110,103,122,54,97,
+ 116,116,101,109,112,116,101,100,32,114,101,108,97,116,105,118,
+ 101,32,105,109,112,111,114,116,32,119,105,116,104,32,110,111,
+ 32,107,110,111,119,110,32,112,97,114,101,110,116,32,112,97,
+ 99,107,97,103,101,122,17,69,109,112,116,121,32,109,111,100,
+ 117,108,101,32,110,97,109,101,78,41,7,218,10,105,115,105,
+ 110,115,116,97,110,99,101,218,3,115,116,114,218,9,84,121,
+ 112,101,69,114,114,111,114,114,46,0,0,0,114,14,0,0,
+ 0,218,10,86,97,108,117,101,69,114,114,111,114,114,80,0,
+ 0,0,169,3,114,17,0,0,0,114,187,0,0,0,114,188,
+ 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,
+ 0,0,218,13,95,115,97,110,105,116,121,95,99,104,101,99,
+ 107,180,3,0,0,115,22,0,0,0,0,2,10,1,18,1,
+ 8,1,8,1,8,1,10,1,10,1,4,1,8,2,12,1,
+ 114,202,0,0,0,122,16,78,111,32,109,111,100,117,108,101,
+ 32,110,97,109,101,100,32,122,4,123,33,114,125,99,2,0,
+ 0,0,0,0,0,0,0,0,0,0,9,0,0,0,8,0,
+ 0,0,67,0,0,0,115,22,1,0,0,100,0,125,2,124,
+ 0,160,0,100,1,161,1,100,2,25,0,125,3,124,3,114,
+ 132,124,3,116,1,106,2,118,1,114,42,116,3,124,1,124,
+ 3,131,2,1,0,124,0,116,1,106,2,118,0,114,62,116,
+ 1,106,2,124,0,25,0,83,0,116,1,106,2,124,3,25,
+ 0,125,4,122,10,124,4,106,4,125,2,87,0,110,48,4,
+ 0,116,5,121,130,1,0,1,0,1,0,116,6,100,3,23,
+ 0,160,7,124,0,124,3,161,2,125,5,116,8,124,5,124,
+ 0,100,4,141,2,100,0,130,2,89,0,110,2,48,0,116,
+ 9,124,0,124,2,131,2,125,6,124,6,100,0,117,0,114,
+ 170,116,8,116,6,160,7,124,0,161,1,124,0,100,4,141,
+ 2,130,1,110,8,116,10,124,6,131,1,125,7,124,3,144,
+ 1,114,18,116,1,106,2,124,3,25,0,125,4,124,0,160,
+ 0,100,1,161,1,100,5,25,0,125,8,122,16,116,11,124,
+ 4,124,8,124,7,131,3,1,0,87,0,110,48,4,0,116,
+ 5,144,1,121,16,1,0,1,0,1,0,100,6,124,3,155,
+ 2,100,7,124,8,155,2,157,4,125,5,116,12,160,13,124,
+ 5,116,14,161,2,1,0,89,0,110,2,48,0,124,7,83,
+ 0,41,8,78,114,129,0,0,0,114,22,0,0,0,122,23,
+ 59,32,123,33,114,125,32,105,115,32,110,111,116,32,97,32,
+ 112,97,99,107,97,103,101,114,16,0,0,0,233,2,0,0,
+ 0,122,27,67,97,110,110,111,116,32,115,101,116,32,97,110,
+ 32,97,116,116,114,105,98,117,116,101,32,111,110,32,122,18,
+ 32,102,111,114,32,99,104,105,108,100,32,109,111,100,117,108,
+ 101,32,41,15,114,130,0,0,0,114,15,0,0,0,114,93,
+ 0,0,0,114,68,0,0,0,114,142,0,0,0,114,107,0,
+ 0,0,218,8,95,69,82,82,95,77,83,71,114,46,0,0,
+ 0,218,19,77,111,100,117,108,101,78,111,116,70,111,117,110,
+ 100,69,114,114,111,114,114,196,0,0,0,114,160,0,0,0,
+ 114,5,0,0,0,114,193,0,0,0,114,194,0,0,0,114,
+ 195,0,0,0,41,9,114,17,0,0,0,218,7,105,109,112,
+ 111,114,116,95,114,166,0,0,0,114,131,0,0,0,90,13,
+ 112,97,114,101,110,116,95,109,111,100,117,108,101,114,158,0,
+ 0,0,114,96,0,0,0,114,97,0,0,0,90,5,99,104,
+ 105,108,100,114,10,0,0,0,114,10,0,0,0,114,11,0,
+ 0,0,218,23,95,102,105,110,100,95,97,110,100,95,108,111,
+ 97,100,95,117,110,108,111,99,107,101,100,199,3,0,0,115,
+ 52,0,0,0,0,1,4,1,14,1,4,1,10,1,10,2,
+ 10,1,10,1,10,1,2,1,10,1,12,1,16,1,20,1,
+ 10,1,8,1,20,2,8,1,6,2,10,1,14,1,2,1,
+ 16,1,14,1,16,1,18,1,114,207,0,0,0,99,2,0,
+ 0,0,0,0,0,0,0,0,0,0,4,0,0,0,8,0,
+ 0,0,67,0,0,0,115,128,0,0,0,116,0,124,0,131,
+ 1,143,62,1,0,116,1,106,2,160,3,124,0,116,4,161,
+ 2,125,2,124,2,116,4,117,0,114,56,116,5,124,0,124,
+ 1,131,2,87,0,2,0,100,1,4,0,4,0,131,3,1,
+ 0,83,0,87,0,100,1,4,0,4,0,131,3,1,0,110,
+ 16,49,0,115,76,48,0,1,0,1,0,1,0,89,0,1,
+ 0,124,2,100,1,117,0,114,116,100,2,160,6,124,0,161,
+ 1,125,3,116,7,124,3,124,0,100,3,141,2,130,1,116,
+ 8,124,0,131,1,1,0,124,2,83,0,41,4,122,25,70,
+ 105,110,100,32,97,110,100,32,108,111,97,100,32,116,104,101,
+ 32,109,111,100,117,108,101,46,78,122,40,105,109,112,111,114,
+ 116,32,111,102,32,123,125,32,104,97,108,116,101,100,59,32,
+ 78,111,110,101,32,105,110,32,115,121,115,46,109,111,100,117,
+ 108,101,115,114,16,0,0,0,41,9,114,51,0,0,0,114,
+ 15,0,0,0,114,93,0,0,0,114,35,0,0,0,218,14,
+ 95,78,69,69,68,83,95,76,79,65,68,73,78,71,114,207,
+ 0,0,0,114,46,0,0,0,114,205,0,0,0,114,66,0,
+ 0,0,41,4,114,17,0,0,0,114,206,0,0,0,114,97,
+ 0,0,0,114,76,0,0,0,114,10,0,0,0,114,10,0,
+ 0,0,114,11,0,0,0,218,14,95,102,105,110,100,95,97,
+ 110,100,95,108,111,97,100,234,3,0,0,115,22,0,0,0,
+ 0,2,10,1,14,1,8,1,54,2,8,1,4,1,2,255,
+ 4,2,12,2,8,1,114,209,0,0,0,114,22,0,0,0,
+ 99,3,0,0,0,0,0,0,0,0,0,0,0,3,0,0,
+ 0,4,0,0,0,67,0,0,0,115,42,0,0,0,116,0,
+ 124,0,124,1,124,2,131,3,1,0,124,2,100,1,107,4,
+ 114,32,116,1,124,0,124,1,124,2,131,3,125,0,116,2,
+ 124,0,116,3,131,2,83,0,41,2,97,50,1,0,0,73,
+ 109,112,111,114,116,32,97,110,100,32,114,101,116,117,114,110,
+ 32,116,104,101,32,109,111,100,117,108,101,32,98,97,115,101,
+ 100,32,111,110,32,105,116,115,32,110,97,109,101,44,32,116,
+ 104,101,32,112,97,99,107,97,103,101,32,116,104,101,32,99,
+ 97,108,108,32,105,115,10,32,32,32,32,98,101,105,110,103,
+ 32,109,97,100,101,32,102,114,111,109,44,32,97,110,100,32,
+ 116,104,101,32,108,101,118,101,108,32,97,100,106,117,115,116,
+ 109,101,110,116,46,10,10,32,32,32,32,84,104,105,115,32,
+ 102,117,110,99,116,105,111,110,32,114,101,112,114,101,115,101,
+ 110,116,115,32,116,104,101,32,103,114,101,97,116,101,115,116,
+ 32,99,111,109,109,111,110,32,100,101,110,111,109,105,110,97,
+ 116,111,114,32,111,102,32,102,117,110,99,116,105,111,110,97,
+ 108,105,116,121,10,32,32,32,32,98,101,116,119,101,101,110,
+ 32,105,109,112,111,114,116,95,109,111,100,117,108,101,32,97,
+ 110,100,32,95,95,105,109,112,111,114,116,95,95,46,32,84,
+ 104,105,115,32,105,110,99,108,117,100,101,115,32,115,101,116,
+ 116,105,110,103,32,95,95,112,97,99,107,97,103,101,95,95,
+ 32,105,102,10,32,32,32,32,116,104,101,32,108,111,97,100,
+ 101,114,32,100,105,100,32,110,111,116,46,10,10,32,32,32,
+ 32,114,22,0,0,0,41,4,114,202,0,0,0,114,189,0,
+ 0,0,114,209,0,0,0,218,11,95,103,99,100,95,105,109,
+ 112,111,114,116,114,201,0,0,0,114,10,0,0,0,114,10,
+ 0,0,0,114,11,0,0,0,114,210,0,0,0,250,3,0,
+ 0,115,8,0,0,0,0,9,12,1,8,1,12,1,114,210,
+ 0,0,0,169,1,218,9,114,101,99,117,114,115,105,118,101,
+ 99,3,0,0,0,0,0,0,0,1,0,0,0,8,0,0,
+ 0,11,0,0,0,67,0,0,0,115,232,0,0,0,124,1,
+ 68,0,93,222,125,4,116,0,124,4,116,1,131,2,115,66,
+ 124,3,114,34,124,0,106,2,100,1,23,0,125,5,110,4,
+ 100,2,125,5,116,3,100,3,124,5,155,0,100,4,116,4,
+ 124,4,131,1,106,2,155,0,157,4,131,1,130,1,113,4,
+ 124,4,100,5,107,2,114,108,124,3,115,226,116,5,124,0,
+ 100,6,131,2,114,226,116,6,124,0,124,0,106,7,124,2,
+ 100,7,100,8,141,4,1,0,113,4,116,5,124,0,124,4,
+ 131,2,115,4,100,9,160,8,124,0,106,2,124,4,161,2,
+ 125,6,122,14,116,9,124,2,124,6,131,2,1,0,87,0,
+ 113,4,4,0,116,10,121,224,1,0,125,7,1,0,122,54,
+ 124,7,106,11,124,6,107,2,114,202,116,12,106,13,160,14,
+ 124,6,116,15,161,2,100,10,117,1,114,202,87,0,89,0,
+ 100,10,125,7,126,7,113,4,130,0,87,0,89,0,100,10,
+ 125,7,126,7,113,4,100,10,125,7,126,7,48,0,48,0,
+ 113,4,124,0,83,0,41,11,122,238,70,105,103,117,114,101,
+ 32,111,117,116,32,119,104,97,116,32,95,95,105,109,112,111,
+ 114,116,95,95,32,115,104,111,117,108,100,32,114,101,116,117,
+ 114,110,46,10,10,32,32,32,32,84,104,101,32,105,109,112,
+ 111,114,116,95,32,112,97,114,97,109,101,116,101,114,32,105,
+ 115,32,97,32,99,97,108,108,97,98,108,101,32,119,104,105,
+ 99,104,32,116,97,107,101,115,32,116,104,101,32,110,97,109,
+ 101,32,111,102,32,109,111,100,117,108,101,32,116,111,10,32,
+ 32,32,32,105,109,112,111,114,116,46,32,73,116,32,105,115,
+ 32,114,101,113,117,105,114,101,100,32,116,111,32,100,101,99,
+ 111,117,112,108,101,32,116,104,101,32,102,117,110,99,116,105,
+ 111,110,32,102,114,111,109,32,97,115,115,117,109,105,110,103,
+ 32,105,109,112,111,114,116,108,105,98,39,115,10,32,32,32,
+ 32,105,109,112,111,114,116,32,105,109,112,108,101,109,101,110,
+ 116,97,116,105,111,110,32,105,115,32,100,101,115,105,114,101,
+ 100,46,10,10,32,32,32,32,122,8,46,95,95,97,108,108,
+ 95,95,122,13,96,96,102,114,111,109,32,108,105,115,116,39,
+ 39,122,8,73,116,101,109,32,105,110,32,122,18,32,109,117,
+ 115,116,32,98,101,32,115,116,114,44,32,110,111,116,32,250,
+ 1,42,218,7,95,95,97,108,108,95,95,84,114,211,0,0,
+ 0,114,184,0,0,0,78,41,16,114,197,0,0,0,114,198,
+ 0,0,0,114,1,0,0,0,114,199,0,0,0,114,14,0,
+ 0,0,114,4,0,0,0,218,16,95,104,97,110,100,108,101,
+ 95,102,114,111,109,108,105,115,116,114,214,0,0,0,114,46,
+ 0,0,0,114,68,0,0,0,114,205,0,0,0,114,17,0,
+ 0,0,114,15,0,0,0,114,93,0,0,0,114,35,0,0,
+ 0,114,208,0,0,0,41,8,114,97,0,0,0,218,8,102,
+ 114,111,109,108,105,115,116,114,206,0,0,0,114,212,0,0,
+ 0,218,1,120,90,5,119,104,101,114,101,90,9,102,114,111,
+ 109,95,110,97,109,101,90,3,101,120,99,114,10,0,0,0,
+ 114,10,0,0,0,114,11,0,0,0,114,215,0,0,0,9,
+ 4,0,0,115,48,0,0,0,0,10,8,1,10,1,4,1,
+ 12,2,4,1,10,1,8,255,10,2,8,1,14,1,10,1,
+ 2,255,8,2,10,1,14,1,2,1,14,1,14,4,10,1,
+ 16,255,2,2,12,1,26,1,114,215,0,0,0,99,1,0,
+ 0,0,0,0,0,0,0,0,0,0,3,0,0,0,6,0,
+ 0,0,67,0,0,0,115,146,0,0,0,124,0,160,0,100,
+ 1,161,1,125,1,124,0,160,0,100,2,161,1,125,2,124,
+ 1,100,3,117,1,114,82,124,2,100,3,117,1,114,78,124,
+ 1,124,2,106,1,107,3,114,78,116,2,106,3,100,4,124,
+ 1,155,2,100,5,124,2,106,1,155,2,100,6,157,5,116,
+ 4,100,7,100,8,141,3,1,0,124,1,83,0,124,2,100,
+ 3,117,1,114,96,124,2,106,1,83,0,116,2,106,3,100,
+ 9,116,4,100,7,100,8,141,3,1,0,124,0,100,10,25,
+ 0,125,1,100,11,124,0,118,1,114,142,124,1,160,5,100,
+ 12,161,1,100,13,25,0,125,1,124,1,83,0,41,14,122,
+ 167,67,97,108,99,117,108,97,116,101,32,119,104,97,116,32,
+ 95,95,112,97,99,107,97,103,101,95,95,32,115,104,111,117,
+ 108,100,32,98,101,46,10,10,32,32,32,32,95,95,112,97,
+ 99,107,97,103,101,95,95,32,105,115,32,110,111,116,32,103,
+ 117,97,114,97,110,116,101,101,100,32,116,111,32,98,101,32,
+ 100,101,102,105,110,101,100,32,111,114,32,99,111,117,108,100,
+ 32,98,101,32,115,101,116,32,116,111,32,78,111,110,101,10,
+ 32,32,32,32,116,111,32,114,101,112,114,101,115,101,110,116,
+ 32,116,104,97,116,32,105,116,115,32,112,114,111,112,101,114,
+ 32,118,97,108,117,101,32,105,115,32,117,110,107,110,111,119,
+ 110,46,10,10,32,32,32,32,114,146,0,0,0,114,106,0,
+ 0,0,78,122,32,95,95,112,97,99,107,97,103,101,95,95,
+ 32,33,61,32,95,95,115,112,101,99,95,95,46,112,97,114,
+ 101,110,116,32,40,122,4,32,33,61,32,250,1,41,233,3,
+ 0,0,0,41,1,90,10,115,116,97,99,107,108,101,118,101,
+ 108,122,89,99,97,110,39,116,32,114,101,115,111,108,118,101,
+ 32,112,97,99,107,97,103,101,32,102,114,111,109,32,95,95,
+ 115,112,101,99,95,95,32,111,114,32,95,95,112,97,99,107,
+ 97,103,101,95,95,44,32,102,97,108,108,105,110,103,32,98,
+ 97,99,107,32,111,110,32,95,95,110,97,109,101,95,95,32,
+ 97,110,100,32,95,95,112,97,116,104,95,95,114,1,0,0,
+ 0,114,142,0,0,0,114,129,0,0,0,114,22,0,0,0,
+ 41,6,114,35,0,0,0,114,131,0,0,0,114,193,0,0,
+ 0,114,194,0,0,0,114,195,0,0,0,114,130,0,0,0,
+ 41,3,218,7,103,108,111,98,97,108,115,114,187,0,0,0,
+ 114,96,0,0,0,114,10,0,0,0,114,10,0,0,0,114,
+ 11,0,0,0,218,17,95,99,97,108,99,95,95,95,112,97,
+ 99,107,97,103,101,95,95,46,4,0,0,115,42,0,0,0,
+ 0,7,10,1,10,1,8,1,18,1,6,1,2,255,4,1,
+ 4,255,6,2,4,254,6,3,4,1,8,1,6,2,6,2,
+ 4,254,6,3,8,1,8,1,14,1,114,221,0,0,0,114,
+ 10,0,0,0,99,5,0,0,0,0,0,0,0,0,0,0,
+ 0,9,0,0,0,5,0,0,0,67,0,0,0,115,180,0,
+ 0,0,124,4,100,1,107,2,114,18,116,0,124,0,131,1,
+ 125,5,110,36,124,1,100,2,117,1,114,30,124,1,110,2,
+ 105,0,125,6,116,1,124,6,131,1,125,7,116,0,124,0,
+ 124,7,124,4,131,3,125,5,124,3,115,150,124,4,100,1,
+ 107,2,114,84,116,0,124,0,160,2,100,3,161,1,100,1,
+ 25,0,131,1,83,0,124,0,115,92,124,5,83,0,116,3,
+ 124,0,131,1,116,3,124,0,160,2,100,3,161,1,100,1,
+ 25,0,131,1,24,0,125,8,116,4,106,5,124,5,106,6,
+ 100,2,116,3,124,5,106,6,131,1,124,8,24,0,133,2,
+ 25,0,25,0,83,0,110,26,116,7,124,5,100,4,131,2,
+ 114,172,116,8,124,5,124,3,116,0,131,3,83,0,124,5,
+ 83,0,100,2,83,0,41,5,97,215,1,0,0,73,109,112,
+ 111,114,116,32,97,32,109,111,100,117,108,101,46,10,10,32,
+ 32,32,32,84,104,101,32,39,103,108,111,98,97,108,115,39,
+ 32,97,114,103,117,109,101,110,116,32,105,115,32,117,115,101,
+ 100,32,116,111,32,105,110,102,101,114,32,119,104,101,114,101,
+ 32,116,104,101,32,105,109,112,111,114,116,32,105,115,32,111,
+ 99,99,117,114,114,105,110,103,32,102,114,111,109,10,32,32,
+ 32,32,116,111,32,104,97,110,100,108,101,32,114,101,108,97,
+ 116,105,118,101,32,105,109,112,111,114,116,115,46,32,84,104,
+ 101,32,39,108,111,99,97,108,115,39,32,97,114,103,117,109,
+ 101,110,116,32,105,115,32,105,103,110,111,114,101,100,46,32,
+ 84,104,101,10,32,32,32,32,39,102,114,111,109,108,105,115,
+ 116,39,32,97,114,103,117,109,101,110,116,32,115,112,101,99,
+ 105,102,105,101,115,32,119,104,97,116,32,115,104,111,117,108,
+ 100,32,101,120,105,115,116,32,97,115,32,97,116,116,114,105,
+ 98,117,116,101,115,32,111,110,32,116,104,101,32,109,111,100,
+ 117,108,101,10,32,32,32,32,98,101,105,110,103,32,105,109,
+ 112,111,114,116,101,100,32,40,101,46,103,46,32,96,96,102,
+ 114,111,109,32,109,111,100,117,108,101,32,105,109,112,111,114,
+ 116,32,60,102,114,111,109,108,105,115,116,62,96,96,41,46,
+ 32,32,84,104,101,32,39,108,101,118,101,108,39,10,32,32,
+ 32,32,97,114,103,117,109,101,110,116,32,114,101,112,114,101,
+ 115,101,110,116,115,32,116,104,101,32,112,97,99,107,97,103,
+ 101,32,108,111,99,97,116,105,111,110,32,116,111,32,105,109,
+ 112,111,114,116,32,102,114,111,109,32,105,110,32,97,32,114,
+ 101,108,97,116,105,118,101,10,32,32,32,32,105,109,112,111,
+ 114,116,32,40,101,46,103,46,32,96,96,102,114,111,109,32,
+ 46,46,112,107,103,32,105,109,112,111,114,116,32,109,111,100,
+ 96,96,32,119,111,117,108,100,32,104,97,118,101,32,97,32,
+ 39,108,101,118,101,108,39,32,111,102,32,50,41,46,10,10,
+ 32,32,32,32,114,22,0,0,0,78,114,129,0,0,0,114,
+ 142,0,0,0,41,9,114,210,0,0,0,114,221,0,0,0,
+ 218,9,112,97,114,116,105,116,105,111,110,114,186,0,0,0,
+ 114,15,0,0,0,114,93,0,0,0,114,1,0,0,0,114,
+ 4,0,0,0,114,215,0,0,0,41,9,114,17,0,0,0,
+ 114,220,0,0,0,218,6,108,111,99,97,108,115,114,216,0,
+ 0,0,114,188,0,0,0,114,97,0,0,0,90,8,103,108,
+ 111,98,97,108,115,95,114,187,0,0,0,90,7,99,117,116,
+ 95,111,102,102,114,10,0,0,0,114,10,0,0,0,114,11,
+ 0,0,0,218,10,95,95,105,109,112,111,114,116,95,95,73,
+ 4,0,0,115,30,0,0,0,0,11,8,1,10,2,16,1,
+ 8,1,12,1,4,3,8,1,18,1,4,1,4,4,26,3,
+ 32,1,10,1,12,2,114,224,0,0,0,99,1,0,0,0,
+ 0,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,
+ 67,0,0,0,115,38,0,0,0,116,0,160,1,124,0,161,
+ 1,125,1,124,1,100,0,117,0,114,30,116,2,100,1,124,
+ 0,23,0,131,1,130,1,116,3,124,1,131,1,83,0,41,
+ 2,78,122,25,110,111,32,98,117,105,108,116,45,105,110,32,
+ 109,111,100,117,108,101,32,110,97,109,101,100,32,41,4,114,
+ 161,0,0,0,114,168,0,0,0,114,80,0,0,0,114,160,
+ 0,0,0,41,2,114,17,0,0,0,114,96,0,0,0,114,
+ 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,18,
+ 95,98,117,105,108,116,105,110,95,102,114,111,109,95,110,97,
+ 109,101,110,4,0,0,115,8,0,0,0,0,1,10,1,8,
+ 1,12,1,114,225,0,0,0,99,2,0,0,0,0,0,0,
+ 0,0,0,0,0,10,0,0,0,5,0,0,0,67,0,0,
+ 0,115,166,0,0,0,124,1,97,0,124,0,97,1,116,2,
+ 116,1,131,1,125,2,116,1,106,3,160,4,161,0,68,0,
+ 93,72,92,2,125,3,125,4,116,5,124,4,124,2,131,2,
+ 114,26,124,3,116,1,106,6,118,0,114,60,116,7,125,5,
+ 110,18,116,0,160,8,124,3,161,1,114,26,116,9,125,5,
+ 110,2,113,26,116,10,124,4,124,5,131,2,125,6,116,11,
+ 124,6,124,4,131,2,1,0,113,26,116,1,106,3,116,12,
+ 25,0,125,7,100,1,68,0,93,46,125,8,124,8,116,1,
+ 106,3,118,1,114,138,116,13,124,8,131,1,125,9,110,10,
+ 116,1,106,3,124,8,25,0,125,9,116,14,124,7,124,8,
+ 124,9,131,3,1,0,113,114,100,2,83,0,41,3,122,250,
+ 83,101,116,117,112,32,105,109,112,111,114,116,108,105,98,32,
+ 98,121,32,105,109,112,111,114,116,105,110,103,32,110,101,101,
+ 100,101,100,32,98,117,105,108,116,45,105,110,32,109,111,100,
+ 117,108,101,115,32,97,110,100,32,105,110,106,101,99,116,105,
+ 110,103,32,116,104,101,109,10,32,32,32,32,105,110,116,111,
+ 32,116,104,101,32,103,108,111,98,97,108,32,110,97,109,101,
+ 115,112,97,99,101,46,10,10,32,32,32,32,65,115,32,115,
+ 121,115,32,105,115,32,110,101,101,100,101,100,32,102,111,114,
+ 32,115,121,115,46,109,111,100,117,108,101,115,32,97,99,99,
+ 101,115,115,32,97,110,100,32,95,105,109,112,32,105,115,32,
+ 110,101,101,100,101,100,32,116,111,32,108,111,97,100,32,98,
+ 117,105,108,116,45,105,110,10,32,32,32,32,109,111,100,117,
+ 108,101,115,44,32,116,104,111,115,101,32,116,119,111,32,109,
+ 111,100,117,108,101,115,32,109,117,115,116,32,98,101,32,101,
+ 120,112,108,105,99,105,116,108,121,32,112,97,115,115,101,100,
+ 32,105,110,46,10,10,32,32,32,32,41,3,114,23,0,0,
+ 0,114,193,0,0,0,114,65,0,0,0,78,41,15,114,58,
+ 0,0,0,114,15,0,0,0,114,14,0,0,0,114,93,0,
+ 0,0,218,5,105,116,101,109,115,114,197,0,0,0,114,79,
+ 0,0,0,114,161,0,0,0,114,89,0,0,0,114,175,0,
+ 0,0,114,143,0,0,0,114,149,0,0,0,114,1,0,0,
+ 0,114,225,0,0,0,114,5,0,0,0,41,10,218,10,115,
+ 121,115,95,109,111,100,117,108,101,218,11,95,105,109,112,95,
+ 109,111,100,117,108,101,90,11,109,111,100,117,108,101,95,116,
+ 121,112,101,114,17,0,0,0,114,97,0,0,0,114,110,0,
+ 0,0,114,96,0,0,0,90,11,115,101,108,102,95,109,111,
+ 100,117,108,101,90,12,98,117,105,108,116,105,110,95,110,97,
+ 109,101,90,14,98,117,105,108,116,105,110,95,109,111,100,117,
+ 108,101,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+ 0,218,6,95,115,101,116,117,112,117,4,0,0,115,36,0,
+ 0,0,0,9,4,1,4,3,8,1,18,1,10,1,10,1,
+ 6,1,10,1,6,2,2,1,10,1,12,3,10,1,8,1,
+ 10,1,10,2,10,1,114,229,0,0,0,99,2,0,0,0,
+ 0,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,
+ 67,0,0,0,115,38,0,0,0,116,0,124,0,124,1,131,
+ 2,1,0,116,1,106,2,160,3,116,4,161,1,1,0,116,
+ 1,106,2,160,3,116,5,161,1,1,0,100,1,83,0,41,
+ 2,122,48,73,110,115,116,97,108,108,32,105,109,112,111,114,
+ 116,101,114,115,32,102,111,114,32,98,117,105,108,116,105,110,
+ 32,97,110,100,32,102,114,111,122,101,110,32,109,111,100,117,
+ 108,101,115,78,41,6,114,229,0,0,0,114,15,0,0,0,
+ 114,192,0,0,0,114,120,0,0,0,114,161,0,0,0,114,
+ 175,0,0,0,41,2,114,227,0,0,0,114,228,0,0,0,
+ 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,
+ 8,95,105,110,115,116,97,108,108,152,4,0,0,115,6,0,
+ 0,0,0,2,10,2,12,1,114,230,0,0,0,99,0,0,
+ 0,0,0,0,0,0,0,0,0,0,1,0,0,0,4,0,
+ 0,0,67,0,0,0,115,32,0,0,0,100,1,100,2,108,
+ 0,125,0,124,0,97,1,124,0,160,2,116,3,106,4,116,
+ 5,25,0,161,1,1,0,100,2,83,0,41,3,122,57,73,
+ 110,115,116,97,108,108,32,105,109,112,111,114,116,101,114,115,
+ 32,116,104,97,116,32,114,101,113,117,105,114,101,32,101,120,
+ 116,101,114,110,97,108,32,102,105,108,101,115,121,115,116,101,
+ 109,32,97,99,99,101,115,115,114,22,0,0,0,78,41,6,
+ 218,26,95,102,114,111,122,101,110,95,105,109,112,111,114,116,
+ 108,105,98,95,101,120,116,101,114,110,97,108,114,127,0,0,
+ 0,114,230,0,0,0,114,15,0,0,0,114,93,0,0,0,
+ 114,1,0,0,0,41,1,114,231,0,0,0,114,10,0,0,
+ 0,114,10,0,0,0,114,11,0,0,0,218,27,95,105,110,
+ 115,116,97,108,108,95,101,120,116,101,114,110,97,108,95,105,
+ 109,112,111,114,116,101,114,115,160,4,0,0,115,6,0,0,
+ 0,0,3,8,1,4,1,114,232,0,0,0,41,2,78,78,
+ 41,1,78,41,2,78,114,22,0,0,0,41,4,78,78,114,
+ 10,0,0,0,114,22,0,0,0,41,50,114,3,0,0,0,
+ 114,127,0,0,0,114,12,0,0,0,114,18,0,0,0,114,
+ 60,0,0,0,114,34,0,0,0,114,44,0,0,0,114,19,
+ 0,0,0,114,20,0,0,0,114,50,0,0,0,114,51,0,
+ 0,0,114,54,0,0,0,114,66,0,0,0,114,68,0,0,
+ 0,114,77,0,0,0,114,87,0,0,0,114,91,0,0,0,
+ 114,98,0,0,0,114,112,0,0,0,114,113,0,0,0,114,
+ 92,0,0,0,114,143,0,0,0,114,149,0,0,0,114,153,
+ 0,0,0,114,108,0,0,0,114,94,0,0,0,114,159,0,
+ 0,0,114,160,0,0,0,114,95,0,0,0,114,161,0,0,
+ 0,114,175,0,0,0,114,180,0,0,0,114,189,0,0,0,
+ 114,191,0,0,0,114,196,0,0,0,114,202,0,0,0,90,
+ 15,95,69,82,82,95,77,83,71,95,80,82,69,70,73,88,
+ 114,204,0,0,0,114,207,0,0,0,218,6,111,98,106,101,
+ 99,116,114,208,0,0,0,114,209,0,0,0,114,210,0,0,
+ 0,114,215,0,0,0,114,221,0,0,0,114,224,0,0,0,
+ 114,225,0,0,0,114,229,0,0,0,114,230,0,0,0,114,
+ 232,0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,
+ 0,0,0,114,11,0,0,0,218,8,60,109,111,100,117,108,
+ 101,62,1,0,0,0,115,94,0,0,0,4,24,4,2,8,
+ 8,8,8,4,2,4,3,16,4,14,77,14,21,14,16,8,
+ 37,8,17,8,11,14,8,8,11,8,12,8,16,8,36,14,
+ 101,16,26,10,45,14,72,8,17,8,17,8,30,8,37,8,
+ 42,8,15,14,75,14,79,14,13,8,9,8,9,10,47,8,
+ 16,4,1,8,2,8,32,6,3,8,16,10,15,14,37,8,
+ 27,10,37,8,7,8,35,8,8,
+};
diff --git a/contrib/tools/python3/src/Python/importlib_external.h b/contrib/tools/python3/src/Python/importlib_external.h
new file mode 100644
index 00000000000..6d40249e9cd
--- /dev/null
+++ b/contrib/tools/python3/src/Python/importlib_external.h
@@ -0,0 +1,2825 @@
+/* Auto-generated by Programs/_freeze_importlib.c */
+const unsigned char _Py_M__importlib_bootstrap_external[] = {
+ 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,5,0,0,0,64,0,0,0,115,224,2,0,0,100,0,
+ 90,0,100,1,100,2,108,1,97,1,100,1,100,2,108,2,
+ 90,2,100,1,100,2,108,3,97,3,100,1,100,2,108,4,
+ 90,4,100,1,100,2,108,5,90,5,116,3,106,6,100,3,
+ 107,2,90,7,101,7,114,76,100,1,100,2,108,8,90,9,
+ 100,1,100,2,108,10,90,10,110,8,100,1,100,2,108,11,
+ 90,9,101,7,114,98,100,4,100,5,103,2,90,12,110,6,
+ 100,5,103,1,90,12,101,13,100,6,100,7,132,0,101,12,
+ 68,0,131,1,131,1,115,126,74,0,130,1,101,12,100,1,
+ 25,0,90,14,101,15,101,12,131,1,90,16,100,8,160,17,
+ 101,12,161,1,90,12,100,9,100,10,132,0,101,12,68,0,
+ 131,1,90,18,100,11,90,19,100,12,90,20,101,20,101,19,
+ 23,0,90,21,100,13,100,14,132,0,90,22,100,15,100,16,
+ 132,0,90,23,100,17,100,18,132,0,90,24,100,19,100,20,
+ 132,0,90,25,101,7,114,228,100,21,100,22,132,0,90,26,
+ 110,8,100,23,100,22,132,0,90,26,100,24,100,25,132,0,
+ 90,27,100,26,100,27,132,0,90,28,100,28,100,29,132,0,
+ 90,29,100,30,100,31,132,0,90,30,100,32,100,33,132,0,
+ 90,31,101,7,144,1,114,36,100,34,100,35,132,0,90,32,
+ 110,8,100,36,100,35,132,0,90,32,100,111,100,38,100,39,
+ 132,1,90,33,101,34,101,33,106,35,131,1,90,36,100,40,
+ 160,37,100,41,100,42,161,2,100,43,23,0,90,38,101,39,
+ 160,40,101,38,100,42,161,2,90,41,100,44,90,42,100,45,
+ 90,43,100,46,103,1,90,44,100,47,103,1,90,45,101,45,
+ 4,0,90,46,90,47,100,112,100,2,100,48,156,1,100,49,
+ 100,50,132,3,90,48,100,51,100,52,132,0,90,49,100,53,
+ 100,54,132,0,90,50,100,55,100,56,132,0,90,51,100,57,
+ 100,58,132,0,90,52,100,59,100,60,132,0,90,53,100,61,
+ 100,62,132,0,90,54,100,63,100,64,132,0,90,55,100,65,
+ 100,66,132,0,90,56,100,67,100,68,132,0,90,57,100,113,
+ 100,69,100,70,132,1,90,58,100,114,100,71,100,72,132,1,
+ 90,59,100,115,100,74,100,75,132,1,90,60,100,76,100,77,
+ 132,0,90,61,101,62,131,0,90,63,100,116,100,2,101,63,
+ 100,78,156,2,100,79,100,80,132,3,90,64,71,0,100,81,
+ 100,82,132,0,100,82,131,2,90,65,71,0,100,83,100,84,
+ 132,0,100,84,131,2,90,66,71,0,100,85,100,86,132,0,
+ 100,86,101,66,131,3,90,67,71,0,100,87,100,88,132,0,
+ 100,88,131,2,90,68,71,0,100,89,100,90,132,0,100,90,
+ 101,68,101,67,131,4,90,69,71,0,100,91,100,92,132,0,
+ 100,92,101,68,101,66,131,4,90,70,103,0,90,71,71,0,
+ 100,93,100,94,132,0,100,94,101,68,101,66,131,4,90,72,
+ 71,0,100,95,100,96,132,0,100,96,131,2,90,73,71,0,
+ 100,97,100,98,132,0,100,98,131,2,90,74,71,0,100,99,
+ 100,100,132,0,100,100,131,2,90,75,71,0,100,101,100,102,
+ 132,0,100,102,131,2,90,76,100,117,100,103,100,104,132,1,
+ 90,77,100,105,100,106,132,0,90,78,100,107,100,108,132,0,
+ 90,79,100,109,100,110,132,0,90,80,100,2,83,0,41,118,
+ 97,94,1,0,0,67,111,114,101,32,105,109,112,108,101,109,
+ 101,110,116,97,116,105,111,110,32,111,102,32,112,97,116,104,
+ 45,98,97,115,101,100,32,105,109,112,111,114,116,46,10,10,
+ 84,104,105,115,32,109,111,100,117,108,101,32,105,115,32,78,
+ 79,84,32,109,101,97,110,116,32,116,111,32,98,101,32,100,
+ 105,114,101,99,116,108,121,32,105,109,112,111,114,116,101,100,
+ 33,32,73,116,32,104,97,115,32,98,101,101,110,32,100,101,
+ 115,105,103,110,101,100,32,115,117,99,104,10,116,104,97,116,
+ 32,105,116,32,99,97,110,32,98,101,32,98,111,111,116,115,
+ 116,114,97,112,112,101,100,32,105,110,116,111,32,80,121,116,
+ 104,111,110,32,97,115,32,116,104,101,32,105,109,112,108,101,
+ 109,101,110,116,97,116,105,111,110,32,111,102,32,105,109,112,
+ 111,114,116,46,32,65,115,10,115,117,99,104,32,105,116,32,
+ 114,101,113,117,105,114,101,115,32,116,104,101,32,105,110,106,
+ 101,99,116,105,111,110,32,111,102,32,115,112,101,99,105,102,
+ 105,99,32,109,111,100,117,108,101,115,32,97,110,100,32,97,
+ 116,116,114,105,98,117,116,101,115,32,105,110,32,111,114,100,
+ 101,114,32,116,111,10,119,111,114,107,46,32,79,110,101,32,
+ 115,104,111,117,108,100,32,117,115,101,32,105,109,112,111,114,
+ 116,108,105,98,32,97,115,32,116,104,101,32,112,117,98,108,
+ 105,99,45,102,97,99,105,110,103,32,118,101,114,115,105,111,
+ 110,32,111,102,32,116,104,105,115,32,109,111,100,117,108,101,
+ 46,10,10,233,0,0,0,0,78,90,5,119,105,110,51,50,
+ 250,1,92,250,1,47,99,1,0,0,0,0,0,0,0,0,
+ 0,0,0,2,0,0,0,3,0,0,0,99,0,0,0,115,
+ 26,0,0,0,124,0,93,18,125,1,116,0,124,1,131,1,
+ 100,0,107,2,86,0,1,0,113,2,100,1,83,0,169,2,
+ 233,1,0,0,0,78,169,1,218,3,108,101,110,169,2,218,
+ 2,46,48,218,3,115,101,112,169,0,114,10,0,0,0,250,
+ 38,60,102,114,111,122,101,110,32,105,109,112,111,114,116,108,
+ 105,98,46,95,98,111,111,116,115,116,114,97,112,95,101,120,
+ 116,101,114,110,97,108,62,218,9,60,103,101,110,101,120,112,
+ 114,62,43,0,0,0,243,0,0,0,0,114,12,0,0,0,
+ 218,0,99,1,0,0,0,0,0,0,0,0,0,0,0,2,
+ 0,0,0,4,0,0,0,67,0,0,0,115,22,0,0,0,
+ 104,0,124,0,93,14,125,1,100,0,124,1,155,0,157,2,
+ 146,2,113,4,83,0,169,1,250,1,58,114,10,0,0,0,
+ 169,2,114,8,0,0,0,218,1,115,114,10,0,0,0,114,
+ 10,0,0,0,114,11,0,0,0,218,9,60,115,101,116,99,
+ 111,109,112,62,47,0,0,0,114,13,0,0,0,114,19,0,
+ 0,0,41,1,218,3,119,105,110,41,2,90,6,99,121,103,
+ 119,105,110,90,6,100,97,114,119,105,110,99,0,0,0,0,
+ 0,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,
+ 3,0,0,0,115,60,0,0,0,116,0,106,1,160,2,116,
+ 3,161,1,114,48,116,0,106,1,160,2,116,4,161,1,114,
+ 30,100,1,137,0,110,4,100,2,137,0,135,0,102,1,100,
+ 3,100,4,132,8,125,0,110,8,100,5,100,4,132,0,125,
+ 0,124,0,83,0,41,6,78,90,12,80,89,84,72,79,78,
+ 67,65,83,69,79,75,115,12,0,0,0,80,89,84,72,79,
+ 78,67,65,83,69,79,75,99,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,2,0,0,0,19,0,0,0,
+ 115,20,0,0,0,116,0,106,1,106,2,12,0,111,18,136,
+ 0,116,3,106,4,118,0,83,0,41,1,122,94,84,114,117,
+ 101,32,105,102,32,102,105,108,101,110,97,109,101,115,32,109,
+ 117,115,116,32,98,101,32,99,104,101,99,107,101,100,32,99,
+ 97,115,101,45,105,110,115,101,110,115,105,116,105,118,101,108,
+ 121,32,97,110,100,32,105,103,110,111,114,101,32,101,110,118,
+ 105,114,111,110,109,101,110,116,32,102,108,97,103,115,32,97,
+ 114,101,32,110,111,116,32,115,101,116,46,41,5,218,3,115,
+ 121,115,218,5,102,108,97,103,115,218,18,105,103,110,111,114,
+ 101,95,101,110,118,105,114,111,110,109,101,110,116,218,3,95,
+ 111,115,90,7,101,110,118,105,114,111,110,114,10,0,0,0,
+ 169,1,218,3,107,101,121,114,10,0,0,0,114,11,0,0,
+ 0,218,11,95,114,101,108,97,120,95,99,97,115,101,64,0,
+ 0,0,115,2,0,0,0,0,2,122,37,95,109,97,107,101,
+ 95,114,101,108,97,120,95,99,97,115,101,46,60,108,111,99,
+ 97,108,115,62,46,95,114,101,108,97,120,95,99,97,115,101,
+ 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,1,0,0,0,83,0,0,0,115,4,0,0,0,100,1,
+ 83,0,41,2,122,53,84,114,117,101,32,105,102,32,102,105,
+ 108,101,110,97,109,101,115,32,109,117,115,116,32,98,101,32,
+ 99,104,101,99,107,101,100,32,99,97,115,101,45,105,110,115,
+ 101,110,115,105,116,105,118,101,108,121,46,70,114,10,0,0,
+ 0,114,10,0,0,0,114,10,0,0,0,114,10,0,0,0,
+ 114,11,0,0,0,114,27,0,0,0,68,0,0,0,115,2,
+ 0,0,0,0,2,41,5,114,21,0,0,0,218,8,112,108,
+ 97,116,102,111,114,109,218,10,115,116,97,114,116,115,119,105,
+ 116,104,218,27,95,67,65,83,69,95,73,78,83,69,78,83,
+ 73,84,73,86,69,95,80,76,65,84,70,79,82,77,83,218,
+ 35,95,67,65,83,69,95,73,78,83,69,78,83,73,84,73,
+ 86,69,95,80,76,65,84,70,79,82,77,83,95,83,84,82,
+ 95,75,69,89,41,1,114,27,0,0,0,114,10,0,0,0,
+ 114,25,0,0,0,114,11,0,0,0,218,16,95,109,97,107,
+ 101,95,114,101,108,97,120,95,99,97,115,101,57,0,0,0,
+ 115,14,0,0,0,0,1,12,1,12,1,6,2,4,2,14,
+ 4,8,3,114,32,0,0,0,99,1,0,0,0,0,0,0,
+ 0,0,0,0,0,1,0,0,0,4,0,0,0,67,0,0,
+ 0,115,20,0,0,0,116,0,124,0,131,1,100,1,64,0,
+ 160,1,100,2,100,3,161,2,83,0,41,4,122,42,67,111,
+ 110,118,101,114,116,32,97,32,51,50,45,98,105,116,32,105,
+ 110,116,101,103,101,114,32,116,111,32,108,105,116,116,108,101,
+ 45,101,110,100,105,97,110,46,236,3,0,0,0,255,127,255,
+ 127,3,0,233,4,0,0,0,218,6,108,105,116,116,108,101,
+ 41,2,218,3,105,110,116,218,8,116,111,95,98,121,116,101,
+ 115,41,1,218,1,120,114,10,0,0,0,114,10,0,0,0,
+ 114,11,0,0,0,218,12,95,112,97,99,107,95,117,105,110,
+ 116,51,50,74,0,0,0,115,2,0,0,0,0,2,114,39,
+ 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,
+ 1,0,0,0,4,0,0,0,67,0,0,0,115,28,0,0,
+ 0,116,0,124,0,131,1,100,1,107,2,115,16,74,0,130,
+ 1,116,1,160,2,124,0,100,2,161,2,83,0,41,3,122,
+ 47,67,111,110,118,101,114,116,32,52,32,98,121,116,101,115,
+ 32,105,110,32,108,105,116,116,108,101,45,101,110,100,105,97,
+ 110,32,116,111,32,97,110,32,105,110,116,101,103,101,114,46,
+ 114,34,0,0,0,114,35,0,0,0,169,3,114,6,0,0,
+ 0,114,36,0,0,0,218,10,102,114,111,109,95,98,121,116,
+ 101,115,169,1,218,4,100,97,116,97,114,10,0,0,0,114,
+ 10,0,0,0,114,11,0,0,0,218,14,95,117,110,112,97,
+ 99,107,95,117,105,110,116,51,50,79,0,0,0,115,4,0,
+ 0,0,0,2,16,1,114,44,0,0,0,99,1,0,0,0,
+ 0,0,0,0,0,0,0,0,1,0,0,0,4,0,0,0,
+ 67,0,0,0,115,28,0,0,0,116,0,124,0,131,1,100,
+ 1,107,2,115,16,74,0,130,1,116,1,160,2,124,0,100,
+ 2,161,2,83,0,41,3,122,47,67,111,110,118,101,114,116,
+ 32,50,32,98,121,116,101,115,32,105,110,32,108,105,116,116,
+ 108,101,45,101,110,100,105,97,110,32,116,111,32,97,110,32,
+ 105,110,116,101,103,101,114,46,233,2,0,0,0,114,35,0,
+ 0,0,114,40,0,0,0,114,42,0,0,0,114,10,0,0,
+ 0,114,10,0,0,0,114,11,0,0,0,218,14,95,117,110,
+ 112,97,99,107,95,117,105,110,116,49,54,84,0,0,0,115,
+ 4,0,0,0,0,2,16,1,114,46,0,0,0,99,0,0,
+ 0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0,
+ 0,0,71,0,0,0,115,228,0,0,0,124,0,115,8,100,
+ 1,83,0,116,0,124,0,131,1,100,2,107,2,114,28,124,
+ 0,100,3,25,0,83,0,100,1,125,1,103,0,125,2,116,
+ 1,116,2,106,3,124,0,131,2,68,0,93,122,92,2,125,
+ 3,125,4,124,3,160,4,116,5,161,1,115,76,124,3,160,
+ 6,116,5,161,1,114,102,124,3,160,7,116,8,161,1,112,
+ 88,124,1,125,1,116,9,124,4,23,0,103,1,125,2,113,
+ 48,124,3,160,6,100,4,161,1,114,152,124,1,160,10,161,
+ 0,124,3,160,10,161,0,107,3,114,140,124,3,125,1,124,
+ 4,103,1,125,2,113,170,124,2,160,11,124,4,161,1,1,
+ 0,113,48,124,3,112,158,124,1,125,1,124,2,160,11,124,
+ 4,161,1,1,0,113,48,100,5,100,6,132,0,124,2,68,
+ 0,131,1,125,2,116,0,124,2,131,1,100,2,107,2,114,
+ 214,124,2,100,3,25,0,115,214,124,1,116,9,23,0,83,
+ 0,124,1,116,9,160,12,124,2,161,1,23,0,83,0,41,
+ 7,250,31,82,101,112,108,97,99,101,109,101,110,116,32,102,
+ 111,114,32,111,115,46,112,97,116,104,46,106,111,105,110,40,
+ 41,46,114,14,0,0,0,114,4,0,0,0,114,0,0,0,
+ 0,114,16,0,0,0,99,1,0,0,0,0,0,0,0,0,
+ 0,0,0,2,0,0,0,5,0,0,0,83,0,0,0,115,
+ 26,0,0,0,103,0,124,0,93,18,125,1,124,1,114,4,
+ 124,1,160,0,116,1,161,1,145,2,113,4,83,0,114,10,
+ 0,0,0,169,2,218,6,114,115,116,114,105,112,218,15,112,
+ 97,116,104,95,115,101,112,97,114,97,116,111,114,115,169,2,
+ 114,8,0,0,0,218,1,112,114,10,0,0,0,114,10,0,
+ 0,0,114,11,0,0,0,218,10,60,108,105,115,116,99,111,
+ 109,112,62,114,0,0,0,114,13,0,0,0,250,30,95,112,
+ 97,116,104,95,106,111,105,110,46,60,108,111,99,97,108,115,
+ 62,46,60,108,105,115,116,99,111,109,112,62,41,13,114,6,
+ 0,0,0,218,3,109,97,112,114,24,0,0,0,218,15,95,
+ 112,97,116,104,95,115,112,108,105,116,114,111,111,116,114,29,
+ 0,0,0,218,14,112,97,116,104,95,115,101,112,95,116,117,
+ 112,108,101,218,8,101,110,100,115,119,105,116,104,114,49,0,
+ 0,0,114,50,0,0,0,218,8,112,97,116,104,95,115,101,
+ 112,218,8,99,97,115,101,102,111,108,100,218,6,97,112,112,
+ 101,110,100,218,4,106,111,105,110,41,5,218,10,112,97,116,
+ 104,95,112,97,114,116,115,218,4,114,111,111,116,218,4,112,
+ 97,116,104,90,8,110,101,119,95,114,111,111,116,218,4,116,
+ 97,105,108,114,10,0,0,0,114,10,0,0,0,114,11,0,
+ 0,0,218,10,95,112,97,116,104,95,106,111,105,110,91,0,
+ 0,0,115,42,0,0,0,0,2,4,1,4,1,12,1,8,
+ 1,4,1,4,1,20,1,20,1,14,1,12,1,10,1,16,
+ 3,4,1,8,2,12,2,8,1,12,1,14,1,20,2,8,
+ 1,114,67,0,0,0,99,0,0,0,0,0,0,0,0,0,
+ 0,0,0,1,0,0,0,4,0,0,0,71,0,0,0,115,
+ 20,0,0,0,116,0,160,1,100,1,100,2,132,0,124,0,
+ 68,0,131,1,161,1,83,0,41,3,114,47,0,0,0,99,
+ 1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,
+ 5,0,0,0,83,0,0,0,115,26,0,0,0,103,0,124,
+ 0,93,18,125,1,124,1,114,4,124,1,160,0,116,1,161,
+ 1,145,2,113,4,83,0,114,10,0,0,0,114,48,0,0,
+ 0,41,2,114,8,0,0,0,218,4,112,97,114,116,114,10,
+ 0,0,0,114,10,0,0,0,114,11,0,0,0,114,53,0,
+ 0,0,123,0,0,0,115,4,0,0,0,6,1,6,255,114,
+ 54,0,0,0,41,2,114,59,0,0,0,114,62,0,0,0,
+ 41,1,114,63,0,0,0,114,10,0,0,0,114,10,0,0,
+ 0,114,11,0,0,0,114,67,0,0,0,121,0,0,0,115,
+ 6,0,0,0,0,2,10,1,2,255,99,1,0,0,0,0,
+ 0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,3,
+ 0,0,0,115,66,0,0,0,116,0,135,0,102,1,100,1,
+ 100,2,132,8,116,1,68,0,131,1,131,1,125,1,124,1,
+ 100,3,107,0,114,38,100,4,136,0,102,2,83,0,136,0,
+ 100,5,124,1,133,2,25,0,136,0,124,1,100,6,23,0,
+ 100,5,133,2,25,0,102,2,83,0,41,7,122,32,82,101,
+ 112,108,97,99,101,109,101,110,116,32,102,111,114,32,111,115,
+ 46,112,97,116,104,46,115,112,108,105,116,40,41,46,99,1,
+ 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,4,
+ 0,0,0,51,0,0,0,115,24,0,0,0,124,0,93,16,
+ 125,1,136,0,160,0,124,1,161,1,86,0,1,0,113,2,
+ 100,0,83,0,169,1,78,41,1,218,5,114,102,105,110,100,
+ 114,51,0,0,0,169,1,114,65,0,0,0,114,10,0,0,
+ 0,114,11,0,0,0,114,12,0,0,0,129,0,0,0,114,
+ 13,0,0,0,122,30,95,112,97,116,104,95,115,112,108,105,
+ 116,46,60,108,111,99,97,108,115,62,46,60,103,101,110,101,
+ 120,112,114,62,114,0,0,0,0,114,14,0,0,0,78,114,
+ 4,0,0,0,41,2,218,3,109,97,120,114,50,0,0,0,
+ 41,2,114,65,0,0,0,218,1,105,114,10,0,0,0,114,
+ 71,0,0,0,114,11,0,0,0,218,11,95,112,97,116,104,
+ 95,115,112,108,105,116,127,0,0,0,115,8,0,0,0,0,
+ 2,22,1,8,1,8,1,114,74,0,0,0,99,1,0,0,
+ 0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0,
+ 0,67,0,0,0,115,10,0,0,0,116,0,160,1,124,0,
+ 161,1,83,0,41,1,122,126,83,116,97,116,32,116,104,101,
+ 32,112,97,116,104,46,10,10,32,32,32,32,77,97,100,101,
+ 32,97,32,115,101,112,97,114,97,116,101,32,102,117,110,99,
+ 116,105,111,110,32,116,111,32,109,97,107,101,32,105,116,32,
+ 101,97,115,105,101,114,32,116,111,32,111,118,101,114,114,105,
+ 100,101,32,105,110,32,101,120,112,101,114,105,109,101,110,116,
+ 115,10,32,32,32,32,40,101,46,103,46,32,99,97,99,104,
+ 101,32,115,116,97,116,32,114,101,115,117,108,116,115,41,46,
+ 10,10,32,32,32,32,41,2,114,24,0,0,0,90,4,115,
+ 116,97,116,114,71,0,0,0,114,10,0,0,0,114,10,0,
+ 0,0,114,11,0,0,0,218,10,95,112,97,116,104,95,115,
+ 116,97,116,135,0,0,0,115,2,0,0,0,0,7,114,75,
+ 0,0,0,99,2,0,0,0,0,0,0,0,0,0,0,0,
+ 3,0,0,0,8,0,0,0,67,0,0,0,115,48,0,0,
+ 0,122,12,116,0,124,0,131,1,125,2,87,0,110,20,4,
+ 0,116,1,121,32,1,0,1,0,1,0,89,0,100,1,83,
+ 0,48,0,124,2,106,2,100,2,64,0,124,1,107,2,83,
+ 0,41,3,122,49,84,101,115,116,32,119,104,101,116,104,101,
+ 114,32,116,104,101,32,112,97,116,104,32,105,115,32,116,104,
+ 101,32,115,112,101,99,105,102,105,101,100,32,109,111,100,101,
+ 32,116,121,112,101,46,70,105,0,240,0,0,41,3,114,75,
+ 0,0,0,218,7,79,83,69,114,114,111,114,218,7,115,116,
+ 95,109,111,100,101,41,3,114,65,0,0,0,218,4,109,111,
+ 100,101,90,9,115,116,97,116,95,105,110,102,111,114,10,0,
+ 0,0,114,10,0,0,0,114,11,0,0,0,218,18,95,112,
+ 97,116,104,95,105,115,95,109,111,100,101,95,116,121,112,101,
+ 145,0,0,0,115,10,0,0,0,0,2,2,1,12,1,12,
+ 1,8,1,114,79,0,0,0,99,1,0,0,0,0,0,0,
+ 0,0,0,0,0,1,0,0,0,3,0,0,0,67,0,0,
+ 0,115,10,0,0,0,116,0,124,0,100,1,131,2,83,0,
+ 41,2,122,31,82,101,112,108,97,99,101,109,101,110,116,32,
+ 102,111,114,32,111,115,46,112,97,116,104,46,105,115,102,105,
+ 108,101,46,105,0,128,0,0,41,1,114,79,0,0,0,114,
+ 71,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,
+ 0,0,0,218,12,95,112,97,116,104,95,105,115,102,105,108,
+ 101,154,0,0,0,115,2,0,0,0,0,2,114,80,0,0,
+ 0,99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,
+ 0,0,3,0,0,0,67,0,0,0,115,22,0,0,0,124,
+ 0,115,12,116,0,160,1,161,0,125,0,116,2,124,0,100,
+ 1,131,2,83,0,41,2,122,30,82,101,112,108,97,99,101,
+ 109,101,110,116,32,102,111,114,32,111,115,46,112,97,116,104,
+ 46,105,115,100,105,114,46,105,0,64,0,0,41,3,114,24,
+ 0,0,0,218,6,103,101,116,99,119,100,114,79,0,0,0,
+ 114,71,0,0,0,114,10,0,0,0,114,10,0,0,0,114,
+ 11,0,0,0,218,11,95,112,97,116,104,95,105,115,100,105,
+ 114,159,0,0,0,115,6,0,0,0,0,2,4,1,8,1,
+ 114,82,0,0,0,99,1,0,0,0,0,0,0,0,0,0,
+ 0,0,2,0,0,0,4,0,0,0,67,0,0,0,115,62,
+ 0,0,0,124,0,115,8,100,1,83,0,116,0,160,1,124,
+ 0,161,1,100,2,25,0,160,2,100,3,100,4,161,2,125,
+ 1,116,3,124,1,131,1,100,5,107,4,111,60,124,1,160,
+ 4,100,6,161,1,112,60,124,1,160,5,100,4,161,1,83,
+ 0,41,7,250,30,82,101,112,108,97,99,101,109,101,110,116,
+ 32,102,111,114,32,111,115,46,112,97,116,104,46,105,115,97,
+ 98,115,46,70,114,0,0,0,0,114,2,0,0,0,114,1,
+ 0,0,0,114,4,0,0,0,122,2,92,92,41,6,114,24,
+ 0,0,0,114,56,0,0,0,218,7,114,101,112,108,97,99,
+ 101,114,6,0,0,0,114,29,0,0,0,114,58,0,0,0,
+ 41,2,114,65,0,0,0,114,64,0,0,0,114,10,0,0,
+ 0,114,10,0,0,0,114,11,0,0,0,218,11,95,112,97,
+ 116,104,95,105,115,97,98,115,167,0,0,0,115,8,0,0,
+ 0,0,2,4,1,4,1,22,1,114,85,0,0,0,99,1,
+ 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,3,
+ 0,0,0,67,0,0,0,115,10,0,0,0,124,0,160,0,
+ 116,1,161,1,83,0,41,1,114,83,0,0,0,41,2,114,
+ 29,0,0,0,114,50,0,0,0,114,71,0,0,0,114,10,
+ 0,0,0,114,10,0,0,0,114,11,0,0,0,114,85,0,
+ 0,0,175,0,0,0,115,2,0,0,0,0,2,233,182,1,
+ 0,0,99,3,0,0,0,0,0,0,0,0,0,0,0,6,
+ 0,0,0,11,0,0,0,67,0,0,0,115,178,0,0,0,
+ 100,1,160,0,124,0,116,1,124,0,131,1,161,2,125,3,
+ 116,2,160,3,124,3,116,2,106,4,116,2,106,5,66,0,
+ 116,2,106,6,66,0,124,2,100,2,64,0,161,3,125,4,
+ 122,70,116,7,160,8,124,4,100,3,161,2,143,26,125,5,
+ 124,5,160,9,124,1,161,1,1,0,87,0,100,4,4,0,
+ 4,0,131,3,1,0,110,16,49,0,115,94,48,0,1,0,
+ 1,0,1,0,89,0,1,0,116,2,160,10,124,3,124,0,
+ 161,2,1,0,87,0,110,54,4,0,116,11,121,172,1,0,
+ 1,0,1,0,122,14,116,2,160,12,124,3,161,1,1,0,
+ 87,0,110,18,4,0,116,11,121,164,1,0,1,0,1,0,
+ 89,0,110,2,48,0,130,0,89,0,110,2,48,0,100,4,
+ 83,0,41,5,122,162,66,101,115,116,45,101,102,102,111,114,
+ 116,32,102,117,110,99,116,105,111,110,32,116,111,32,119,114,
+ 105,116,101,32,100,97,116,97,32,116,111,32,97,32,112,97,
+ 116,104,32,97,116,111,109,105,99,97,108,108,121,46,10,32,
+ 32,32,32,66,101,32,112,114,101,112,97,114,101,100,32,116,
+ 111,32,104,97,110,100,108,101,32,97,32,70,105,108,101,69,
+ 120,105,115,116,115,69,114,114,111,114,32,105,102,32,99,111,
+ 110,99,117,114,114,101,110,116,32,119,114,105,116,105,110,103,
+ 32,111,102,32,116,104,101,10,32,32,32,32,116,101,109,112,
+ 111,114,97,114,121,32,102,105,108,101,32,105,115,32,97,116,
+ 116,101,109,112,116,101,100,46,250,5,123,125,46,123,125,114,
+ 86,0,0,0,90,2,119,98,78,41,13,218,6,102,111,114,
+ 109,97,116,218,2,105,100,114,24,0,0,0,90,4,111,112,
+ 101,110,90,6,79,95,69,88,67,76,90,7,79,95,67,82,
+ 69,65,84,90,8,79,95,87,82,79,78,76,89,218,3,95,
+ 105,111,218,6,70,105,108,101,73,79,218,5,119,114,105,116,
+ 101,114,84,0,0,0,114,76,0,0,0,90,6,117,110,108,
+ 105,110,107,41,6,114,65,0,0,0,114,43,0,0,0,114,
+ 78,0,0,0,90,8,112,97,116,104,95,116,109,112,90,2,
+ 102,100,218,4,102,105,108,101,114,10,0,0,0,114,10,0,
+ 0,0,114,11,0,0,0,218,13,95,119,114,105,116,101,95,
+ 97,116,111,109,105,99,180,0,0,0,115,28,0,0,0,0,
+ 5,16,1,6,1,22,255,4,2,2,3,14,1,40,1,16,
+ 1,12,1,2,1,14,1,12,1,6,1,114,94,0,0,0,
+ 105,97,13,0,0,114,45,0,0,0,114,35,0,0,0,115,
+ 2,0,0,0,13,10,90,11,95,95,112,121,99,97,99,104,
+ 101,95,95,122,4,111,112,116,45,122,3,46,112,121,122,4,
+ 46,112,121,99,41,1,218,12,111,112,116,105,109,105,122,97,
+ 116,105,111,110,99,2,0,0,0,0,0,0,0,1,0,0,
+ 0,12,0,0,0,5,0,0,0,67,0,0,0,115,88,1,
+ 0,0,124,1,100,1,117,1,114,52,116,0,160,1,100,2,
+ 116,2,161,2,1,0,124,2,100,1,117,1,114,40,100,3,
+ 125,3,116,3,124,3,131,1,130,1,124,1,114,48,100,4,
+ 110,2,100,5,125,2,116,4,160,5,124,0,161,1,125,0,
+ 116,6,124,0,131,1,92,2,125,4,125,5,124,5,160,7,
+ 100,6,161,1,92,3,125,6,125,7,125,8,116,8,106,9,
+ 106,10,125,9,124,9,100,1,117,0,114,114,116,11,100,7,
+ 131,1,130,1,100,4,160,12,124,6,114,126,124,6,110,2,
+ 124,8,124,7,124,9,103,3,161,1,125,10,124,2,100,1,
+ 117,0,114,172,116,8,106,13,106,14,100,8,107,2,114,164,
+ 100,4,125,2,110,8,116,8,106,13,106,14,125,2,116,15,
+ 124,2,131,1,125,2,124,2,100,4,107,3,114,224,124,2,
+ 160,16,161,0,115,210,116,17,100,9,160,18,124,2,161,1,
+ 131,1,130,1,100,10,160,18,124,10,116,19,124,2,161,3,
+ 125,10,124,10,116,20,100,8,25,0,23,0,125,11,116,8,
+ 106,21,100,1,117,1,144,1,114,76,116,22,124,4,131,1,
+ 144,1,115,16,116,23,116,4,160,24,161,0,124,4,131,2,
+ 125,4,124,4,100,5,25,0,100,11,107,2,144,1,114,56,
+ 124,4,100,8,25,0,116,25,118,1,144,1,114,56,124,4,
+ 100,12,100,1,133,2,25,0,125,4,116,23,116,8,106,21,
+ 124,4,160,26,116,25,161,1,124,11,131,3,83,0,116,23,
+ 124,4,116,27,124,11,131,3,83,0,41,13,97,254,2,0,
+ 0,71,105,118,101,110,32,116,104,101,32,112,97,116,104,32,
+ 116,111,32,97,32,46,112,121,32,102,105,108,101,44,32,114,
+ 101,116,117,114,110,32,116,104,101,32,112,97,116,104,32,116,
+ 111,32,105,116,115,32,46,112,121,99,32,102,105,108,101,46,
+ 10,10,32,32,32,32,84,104,101,32,46,112,121,32,102,105,
+ 108,101,32,100,111,101,115,32,110,111,116,32,110,101,101,100,
+ 32,116,111,32,101,120,105,115,116,59,32,116,104,105,115,32,
+ 115,105,109,112,108,121,32,114,101,116,117,114,110,115,32,116,
+ 104,101,32,112,97,116,104,32,116,111,32,116,104,101,10,32,
+ 32,32,32,46,112,121,99,32,102,105,108,101,32,99,97,108,
+ 99,117,108,97,116,101,100,32,97,115,32,105,102,32,116,104,
+ 101,32,46,112,121,32,102,105,108,101,32,119,101,114,101,32,
+ 105,109,112,111,114,116,101,100,46,10,10,32,32,32,32,84,
+ 104,101,32,39,111,112,116,105,109,105,122,97,116,105,111,110,
+ 39,32,112,97,114,97,109,101,116,101,114,32,99,111,110,116,
+ 114,111,108,115,32,116,104,101,32,112,114,101,115,117,109,101,
+ 100,32,111,112,116,105,109,105,122,97,116,105,111,110,32,108,
+ 101,118,101,108,32,111,102,10,32,32,32,32,116,104,101,32,
+ 98,121,116,101,99,111,100,101,32,102,105,108,101,46,32,73,
+ 102,32,39,111,112,116,105,109,105,122,97,116,105,111,110,39,
+ 32,105,115,32,110,111,116,32,78,111,110,101,44,32,116,104,
+ 101,32,115,116,114,105,110,103,32,114,101,112,114,101,115,101,
+ 110,116,97,116,105,111,110,10,32,32,32,32,111,102,32,116,
+ 104,101,32,97,114,103,117,109,101,110,116,32,105,115,32,116,
+ 97,107,101,110,32,97,110,100,32,118,101,114,105,102,105,101,
+ 100,32,116,111,32,98,101,32,97,108,112,104,97,110,117,109,
+ 101,114,105,99,32,40,101,108,115,101,32,86,97,108,117,101,
+ 69,114,114,111,114,10,32,32,32,32,105,115,32,114,97,105,
+ 115,101,100,41,46,10,10,32,32,32,32,84,104,101,32,100,
+ 101,98,117,103,95,111,118,101,114,114,105,100,101,32,112,97,
+ 114,97,109,101,116,101,114,32,105,115,32,100,101,112,114,101,
+ 99,97,116,101,100,46,32,73,102,32,100,101,98,117,103,95,
+ 111,118,101,114,114,105,100,101,32,105,115,32,110,111,116,32,
+ 78,111,110,101,44,10,32,32,32,32,97,32,84,114,117,101,
+ 32,118,97,108,117,101,32,105,115,32,116,104,101,32,115,97,
+ 109,101,32,97,115,32,115,101,116,116,105,110,103,32,39,111,
+ 112,116,105,109,105,122,97,116,105,111,110,39,32,116,111,32,
+ 116,104,101,32,101,109,112,116,121,32,115,116,114,105,110,103,
+ 10,32,32,32,32,119,104,105,108,101,32,97,32,70,97,108,
+ 115,101,32,118,97,108,117,101,32,105,115,32,101,113,117,105,
+ 118,97,108,101,110,116,32,116,111,32,115,101,116,116,105,110,
+ 103,32,39,111,112,116,105,109,105,122,97,116,105,111,110,39,
+ 32,116,111,32,39,49,39,46,10,10,32,32,32,32,73,102,
+ 32,115,121,115,46,105,109,112,108,101,109,101,110,116,97,116,
+ 105,111,110,46,99,97,99,104,101,95,116,97,103,32,105,115,
+ 32,78,111,110,101,32,116,104,101,110,32,78,111,116,73,109,
+ 112,108,101,109,101,110,116,101,100,69,114,114,111,114,32,105,
+ 115,32,114,97,105,115,101,100,46,10,10,32,32,32,32,78,
+ 122,70,116,104,101,32,100,101,98,117,103,95,111,118,101,114,
+ 114,105,100,101,32,112,97,114,97,109,101,116,101,114,32,105,
+ 115,32,100,101,112,114,101,99,97,116,101,100,59,32,117,115,
+ 101,32,39,111,112,116,105,109,105,122,97,116,105,111,110,39,
+ 32,105,110,115,116,101,97,100,122,50,100,101,98,117,103,95,
+ 111,118,101,114,114,105,100,101,32,111,114,32,111,112,116,105,
+ 109,105,122,97,116,105,111,110,32,109,117,115,116,32,98,101,
+ 32,115,101,116,32,116,111,32,78,111,110,101,114,14,0,0,
+ 0,114,4,0,0,0,218,1,46,250,36,115,121,115,46,105,
+ 109,112,108,101,109,101,110,116,97,116,105,111,110,46,99,97,
+ 99,104,101,95,116,97,103,32,105,115,32,78,111,110,101,114,
+ 0,0,0,0,122,24,123,33,114,125,32,105,115,32,110,111,
+ 116,32,97,108,112,104,97,110,117,109,101,114,105,99,122,7,
+ 123,125,46,123,125,123,125,114,16,0,0,0,114,45,0,0,
+ 0,41,28,218,9,95,119,97,114,110,105,110,103,115,218,4,
+ 119,97,114,110,218,18,68,101,112,114,101,99,97,116,105,111,
+ 110,87,97,114,110,105,110,103,218,9,84,121,112,101,69,114,
+ 114,111,114,114,24,0,0,0,218,6,102,115,112,97,116,104,
+ 114,74,0,0,0,218,10,114,112,97,114,116,105,116,105,111,
+ 110,114,21,0,0,0,218,14,105,109,112,108,101,109,101,110,
+ 116,97,116,105,111,110,218,9,99,97,99,104,101,95,116,97,
+ 103,218,19,78,111,116,73,109,112,108,101,109,101,110,116,101,
+ 100,69,114,114,111,114,114,62,0,0,0,114,22,0,0,0,
+ 218,8,111,112,116,105,109,105,122,101,218,3,115,116,114,218,
+ 7,105,115,97,108,110,117,109,218,10,86,97,108,117,101,69,
+ 114,114,111,114,114,88,0,0,0,218,4,95,79,80,84,218,
+ 17,66,89,84,69,67,79,68,69,95,83,85,70,70,73,88,
+ 69,83,218,14,112,121,99,97,99,104,101,95,112,114,101,102,
+ 105,120,114,85,0,0,0,114,67,0,0,0,114,81,0,0,
+ 0,114,50,0,0,0,218,6,108,115,116,114,105,112,218,8,
+ 95,80,89,67,65,67,72,69,41,12,114,65,0,0,0,90,
+ 14,100,101,98,117,103,95,111,118,101,114,114,105,100,101,114,
+ 95,0,0,0,218,7,109,101,115,115,97,103,101,218,4,104,
+ 101,97,100,114,66,0,0,0,90,4,98,97,115,101,114,9,
+ 0,0,0,218,4,114,101,115,116,90,3,116,97,103,90,15,
+ 97,108,109,111,115,116,95,102,105,108,101,110,97,109,101,218,
+ 8,102,105,108,101,110,97,109,101,114,10,0,0,0,114,10,
+ 0,0,0,114,11,0,0,0,218,17,99,97,99,104,101,95,
+ 102,114,111,109,95,115,111,117,114,99,101,105,1,0,0,115,
+ 72,0,0,0,0,18,8,1,6,1,2,255,4,2,8,1,
+ 4,1,8,1,12,1,10,1,12,1,16,1,8,1,8,1,
+ 8,1,24,1,8,1,12,1,6,2,8,1,8,1,8,1,
+ 8,1,14,1,14,1,12,1,12,9,10,1,14,5,28,1,
+ 12,4,2,1,4,1,8,1,2,253,4,5,114,120,0,0,
+ 0,99,1,0,0,0,0,0,0,0,0,0,0,0,10,0,
+ 0,0,5,0,0,0,67,0,0,0,115,46,1,0,0,116,
+ 0,106,1,106,2,100,1,117,0,114,20,116,3,100,2,131,
+ 1,130,1,116,4,160,5,124,0,161,1,125,0,116,6,124,
+ 0,131,1,92,2,125,1,125,2,100,3,125,3,116,0,106,
+ 7,100,1,117,1,114,102,116,0,106,7,160,8,116,9,161,
+ 1,125,4,124,1,160,10,124,4,116,11,23,0,161,1,114,
+ 102,124,1,116,12,124,4,131,1,100,1,133,2,25,0,125,
+ 1,100,4,125,3,124,3,115,144,116,6,124,1,131,1,92,
+ 2,125,1,125,5,124,5,116,13,107,3,114,144,116,14,116,
+ 13,155,0,100,5,124,0,155,2,157,3,131,1,130,1,124,
+ 2,160,15,100,6,161,1,125,6,124,6,100,7,118,1,114,
+ 178,116,14,100,8,124,2,155,2,157,2,131,1,130,1,110,
+ 92,124,6,100,9,107,2,144,1,114,14,124,2,160,16,100,
+ 6,100,10,161,2,100,11,25,0,125,7,124,7,160,10,116,
+ 17,161,1,115,228,116,14,100,12,116,17,155,2,157,2,131,
+ 1,130,1,124,7,116,12,116,17,131,1,100,1,133,2,25,
+ 0,125,8,124,8,160,18,161,0,144,1,115,14,116,14,100,
+ 13,124,7,155,2,100,14,157,3,131,1,130,1,124,2,160,
+ 19,100,6,161,1,100,15,25,0,125,9,116,20,124,1,124,
+ 9,116,21,100,15,25,0,23,0,131,2,83,0,41,16,97,
+ 110,1,0,0,71,105,118,101,110,32,116,104,101,32,112,97,
+ 116,104,32,116,111,32,97,32,46,112,121,99,46,32,102,105,
+ 108,101,44,32,114,101,116,117,114,110,32,116,104,101,32,112,
+ 97,116,104,32,116,111,32,105,116,115,32,46,112,121,32,102,
+ 105,108,101,46,10,10,32,32,32,32,84,104,101,32,46,112,
+ 121,99,32,102,105,108,101,32,100,111,101,115,32,110,111,116,
+ 32,110,101,101,100,32,116,111,32,101,120,105,115,116,59,32,
+ 116,104,105,115,32,115,105,109,112,108,121,32,114,101,116,117,
+ 114,110,115,32,116,104,101,32,112,97,116,104,32,116,111,10,
+ 32,32,32,32,116,104,101,32,46,112,121,32,102,105,108,101,
+ 32,99,97,108,99,117,108,97,116,101,100,32,116,111,32,99,
+ 111,114,114,101,115,112,111,110,100,32,116,111,32,116,104,101,
+ 32,46,112,121,99,32,102,105,108,101,46,32,32,73,102,32,
+ 112,97,116,104,32,100,111,101,115,10,32,32,32,32,110,111,
+ 116,32,99,111,110,102,111,114,109,32,116,111,32,80,69,80,
+ 32,51,49,52,55,47,52,56,56,32,102,111,114,109,97,116,
+ 44,32,86,97,108,117,101,69,114,114,111,114,32,119,105,108,
+ 108,32,98,101,32,114,97,105,115,101,100,46,32,73,102,10,
+ 32,32,32,32,115,121,115,46,105,109,112,108,101,109,101,110,
+ 116,97,116,105,111,110,46,99,97,99,104,101,95,116,97,103,
+ 32,105,115,32,78,111,110,101,32,116,104,101,110,32,78,111,
+ 116,73,109,112,108,101,109,101,110,116,101,100,69,114,114,111,
+ 114,32,105,115,32,114,97,105,115,101,100,46,10,10,32,32,
+ 32,32,78,114,97,0,0,0,70,84,122,31,32,110,111,116,
+ 32,98,111,116,116,111,109,45,108,101,118,101,108,32,100,105,
+ 114,101,99,116,111,114,121,32,105,110,32,114,96,0,0,0,
+ 62,2,0,0,0,114,45,0,0,0,233,3,0,0,0,122,
+ 29,101,120,112,101,99,116,101,100,32,111,110,108,121,32,50,
+ 32,111,114,32,51,32,100,111,116,115,32,105,110,32,114,121,
+ 0,0,0,114,45,0,0,0,233,254,255,255,255,122,53,111,
+ 112,116,105,109,105,122,97,116,105,111,110,32,112,111,114,116,
+ 105,111,110,32,111,102,32,102,105,108,101,110,97,109,101,32,
+ 100,111,101,115,32,110,111,116,32,115,116,97,114,116,32,119,
+ 105,116,104,32,122,19,111,112,116,105,109,105,122,97,116,105,
+ 111,110,32,108,101,118,101,108,32,122,29,32,105,115,32,110,
+ 111,116,32,97,110,32,97,108,112,104,97,110,117,109,101,114,
+ 105,99,32,118,97,108,117,101,114,0,0,0,0,41,22,114,
+ 21,0,0,0,114,104,0,0,0,114,105,0,0,0,114,106,
+ 0,0,0,114,24,0,0,0,114,102,0,0,0,114,74,0,
+ 0,0,114,113,0,0,0,114,49,0,0,0,114,50,0,0,
+ 0,114,29,0,0,0,114,59,0,0,0,114,6,0,0,0,
+ 114,115,0,0,0,114,110,0,0,0,218,5,99,111,117,110,
+ 116,218,6,114,115,112,108,105,116,114,111,0,0,0,114,109,
+ 0,0,0,218,9,112,97,114,116,105,116,105,111,110,114,67,
+ 0,0,0,218,15,83,79,85,82,67,69,95,83,85,70,70,
+ 73,88,69,83,41,10,114,65,0,0,0,114,117,0,0,0,
+ 90,16,112,121,99,97,99,104,101,95,102,105,108,101,110,97,
+ 109,101,90,23,102,111,117,110,100,95,105,110,95,112,121,99,
+ 97,99,104,101,95,112,114,101,102,105,120,90,13,115,116,114,
+ 105,112,112,101,100,95,112,97,116,104,90,7,112,121,99,97,
+ 99,104,101,90,9,100,111,116,95,99,111,117,110,116,114,95,
+ 0,0,0,90,9,111,112,116,95,108,101,118,101,108,90,13,
+ 98,97,115,101,95,102,105,108,101,110,97,109,101,114,10,0,
+ 0,0,114,10,0,0,0,114,11,0,0,0,218,17,115,111,
+ 117,114,99,101,95,102,114,111,109,95,99,97,99,104,101,176,
+ 1,0,0,115,60,0,0,0,0,9,12,1,8,1,10,1,
+ 12,1,4,1,10,1,12,1,14,1,16,1,4,1,4,1,
+ 12,1,8,1,8,1,2,255,8,2,10,1,8,1,16,1,
+ 10,1,16,1,10,1,4,1,2,255,8,2,16,1,10,1,
+ 16,2,14,1,114,127,0,0,0,99,1,0,0,0,0,0,
+ 0,0,0,0,0,0,5,0,0,0,9,0,0,0,67,0,
+ 0,0,115,124,0,0,0,116,0,124,0,131,1,100,1,107,
+ 2,114,16,100,2,83,0,124,0,160,1,100,3,161,1,92,
+ 3,125,1,125,2,125,3,124,1,114,56,124,3,160,2,161,
+ 0,100,4,100,5,133,2,25,0,100,6,107,3,114,60,124,
+ 0,83,0,122,12,116,3,124,0,131,1,125,4,87,0,110,
+ 34,4,0,116,4,116,5,102,2,121,106,1,0,1,0,1,
+ 0,124,0,100,2,100,5,133,2,25,0,125,4,89,0,110,
+ 2,48,0,116,6,124,4,131,1,114,120,124,4,83,0,124,
+ 0,83,0,41,7,122,188,67,111,110,118,101,114,116,32,97,
+ 32,98,121,116,101,99,111,100,101,32,102,105,108,101,32,112,
+ 97,116,104,32,116,111,32,97,32,115,111,117,114,99,101,32,
+ 112,97,116,104,32,40,105,102,32,112,111,115,115,105,98,108,
+ 101,41,46,10,10,32,32,32,32,84,104,105,115,32,102,117,
+ 110,99,116,105,111,110,32,101,120,105,115,116,115,32,112,117,
+ 114,101,108,121,32,102,111,114,32,98,97,99,107,119,97,114,
+ 100,115,45,99,111,109,112,97,116,105,98,105,108,105,116,121,
+ 32,102,111,114,10,32,32,32,32,80,121,73,109,112,111,114,
+ 116,95,69,120,101,99,67,111,100,101,77,111,100,117,108,101,
+ 87,105,116,104,70,105,108,101,110,97,109,101,115,40,41,32,
+ 105,110,32,116,104,101,32,67,32,65,80,73,46,10,10,32,
+ 32,32,32,114,0,0,0,0,78,114,96,0,0,0,233,253,
+ 255,255,255,233,255,255,255,255,90,2,112,121,41,7,114,6,
+ 0,0,0,114,103,0,0,0,218,5,108,111,119,101,114,114,
+ 127,0,0,0,114,106,0,0,0,114,110,0,0,0,114,80,
+ 0,0,0,41,5,218,13,98,121,116,101,99,111,100,101,95,
+ 112,97,116,104,114,118,0,0,0,218,1,95,90,9,101,120,
+ 116,101,110,115,105,111,110,218,11,115,111,117,114,99,101,95,
+ 112,97,116,104,114,10,0,0,0,114,10,0,0,0,114,11,
+ 0,0,0,218,15,95,103,101,116,95,115,111,117,114,99,101,
+ 102,105,108,101,216,1,0,0,115,20,0,0,0,0,7,12,
+ 1,4,1,16,1,24,1,4,1,2,1,12,1,16,1,18,
+ 1,114,134,0,0,0,99,1,0,0,0,0,0,0,0,0,
+ 0,0,0,1,0,0,0,8,0,0,0,67,0,0,0,115,
+ 72,0,0,0,124,0,160,0,116,1,116,2,131,1,161,1,
+ 114,46,122,10,116,3,124,0,131,1,87,0,83,0,4,0,
+ 116,4,121,42,1,0,1,0,1,0,89,0,113,68,48,0,
+ 110,22,124,0,160,0,116,1,116,5,131,1,161,1,114,64,
+ 124,0,83,0,100,0,83,0,100,0,83,0,114,69,0,0,
+ 0,41,6,114,58,0,0,0,218,5,116,117,112,108,101,114,
+ 126,0,0,0,114,120,0,0,0,114,106,0,0,0,114,112,
+ 0,0,0,41,1,114,119,0,0,0,114,10,0,0,0,114,
+ 10,0,0,0,114,11,0,0,0,218,11,95,103,101,116,95,
+ 99,97,99,104,101,100,235,1,0,0,115,16,0,0,0,0,
+ 1,14,1,2,1,10,1,12,1,8,1,14,1,4,2,114,
+ 136,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,
+ 0,2,0,0,0,8,0,0,0,67,0,0,0,115,50,0,
+ 0,0,122,14,116,0,124,0,131,1,106,1,125,1,87,0,
+ 110,22,4,0,116,2,121,36,1,0,1,0,1,0,100,1,
+ 125,1,89,0,110,2,48,0,124,1,100,2,79,0,125,1,
+ 124,1,83,0,41,3,122,51,67,97,108,99,117,108,97,116,
+ 101,32,116,104,101,32,109,111,100,101,32,112,101,114,109,105,
+ 115,115,105,111,110,115,32,102,111,114,32,97,32,98,121,116,
+ 101,99,111,100,101,32,102,105,108,101,46,114,86,0,0,0,
+ 233,128,0,0,0,41,3,114,75,0,0,0,114,77,0,0,
+ 0,114,76,0,0,0,41,2,114,65,0,0,0,114,78,0,
+ 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+ 0,218,10,95,99,97,108,99,95,109,111,100,101,247,1,0,
+ 0,115,12,0,0,0,0,2,2,1,14,1,12,1,10,3,
+ 8,1,114,138,0,0,0,99,1,0,0,0,0,0,0,0,
+ 0,0,0,0,3,0,0,0,8,0,0,0,3,0,0,0,
+ 115,66,0,0,0,100,6,135,0,102,1,100,2,100,3,132,
+ 9,125,1,122,10,116,0,106,1,125,2,87,0,110,26,4,
+ 0,116,2,121,50,1,0,1,0,1,0,100,4,100,5,132,
+ 0,125,2,89,0,110,2,48,0,124,2,124,1,136,0,131,
+ 2,1,0,124,1,83,0,41,7,122,252,68,101,99,111,114,
+ 97,116,111,114,32,116,111,32,118,101,114,105,102,121,32,116,
+ 104,97,116,32,116,104,101,32,109,111,100,117,108,101,32,98,
+ 101,105,110,103,32,114,101,113,117,101,115,116,101,100,32,109,
+ 97,116,99,104,101,115,32,116,104,101,32,111,110,101,32,116,
+ 104,101,10,32,32,32,32,108,111,97,100,101,114,32,99,97,
+ 110,32,104,97,110,100,108,101,46,10,10,32,32,32,32,84,
+ 104,101,32,102,105,114,115,116,32,97,114,103,117,109,101,110,
+ 116,32,40,115,101,108,102,41,32,109,117,115,116,32,100,101,
+ 102,105,110,101,32,95,110,97,109,101,32,119,104,105,99,104,
+ 32,116,104,101,32,115,101,99,111,110,100,32,97,114,103,117,
+ 109,101,110,116,32,105,115,10,32,32,32,32,99,111,109,112,
+ 97,114,101,100,32,97,103,97,105,110,115,116,46,32,73,102,
+ 32,116,104,101,32,99,111,109,112,97,114,105,115,111,110,32,
+ 102,97,105,108,115,32,116,104,101,110,32,73,109,112,111,114,
+ 116,69,114,114,111,114,32,105,115,32,114,97,105,115,101,100,
+ 46,10,10,32,32,32,32,78,99,2,0,0,0,0,0,0,
+ 0,0,0,0,0,4,0,0,0,4,0,0,0,31,0,0,
+ 0,115,72,0,0,0,124,1,100,0,117,0,114,16,124,0,
+ 106,0,125,1,110,32,124,0,106,0,124,1,107,3,114,48,
+ 116,1,100,1,124,0,106,0,124,1,102,2,22,0,124,1,
+ 100,2,141,2,130,1,136,0,124,0,124,1,103,2,124,2,
+ 162,1,82,0,105,0,124,3,164,1,142,1,83,0,41,3,
+ 78,122,30,108,111,97,100,101,114,32,102,111,114,32,37,115,
+ 32,99,97,110,110,111,116,32,104,97,110,100,108,101,32,37,
+ 115,169,1,218,4,110,97,109,101,41,2,114,140,0,0,0,
+ 218,11,73,109,112,111,114,116,69,114,114,111,114,41,4,218,
+ 4,115,101,108,102,114,140,0,0,0,218,4,97,114,103,115,
+ 218,6,107,119,97,114,103,115,169,1,218,6,109,101,116,104,
+ 111,100,114,10,0,0,0,114,11,0,0,0,218,19,95,99,
+ 104,101,99,107,95,110,97,109,101,95,119,114,97,112,112,101,
+ 114,11,2,0,0,115,18,0,0,0,0,1,8,1,8,1,
+ 10,1,4,1,8,255,2,1,2,255,6,2,122,40,95,99,
+ 104,101,99,107,95,110,97,109,101,46,60,108,111,99,97,108,
+ 115,62,46,95,99,104,101,99,107,95,110,97,109,101,95,119,
+ 114,97,112,112,101,114,99,2,0,0,0,0,0,0,0,0,
+ 0,0,0,3,0,0,0,7,0,0,0,83,0,0,0,115,
+ 56,0,0,0,100,1,68,0,93,32,125,2,116,0,124,1,
+ 124,2,131,2,114,4,116,1,124,0,124,2,116,2,124,1,
+ 124,2,131,2,131,3,1,0,113,4,124,0,106,3,160,4,
+ 124,1,106,3,161,1,1,0,100,0,83,0,41,2,78,41,
+ 4,218,10,95,95,109,111,100,117,108,101,95,95,218,8,95,
+ 95,110,97,109,101,95,95,218,12,95,95,113,117,97,108,110,
+ 97,109,101,95,95,218,7,95,95,100,111,99,95,95,41,5,
+ 218,7,104,97,115,97,116,116,114,218,7,115,101,116,97,116,
+ 116,114,218,7,103,101,116,97,116,116,114,218,8,95,95,100,
+ 105,99,116,95,95,218,6,117,112,100,97,116,101,41,3,90,
+ 3,110,101,119,90,3,111,108,100,114,84,0,0,0,114,10,
+ 0,0,0,114,10,0,0,0,114,11,0,0,0,218,5,95,
+ 119,114,97,112,22,2,0,0,115,8,0,0,0,0,1,8,
+ 1,10,1,20,1,122,26,95,99,104,101,99,107,95,110,97,
+ 109,101,46,60,108,111,99,97,108,115,62,46,95,119,114,97,
+ 112,41,1,78,41,3,218,10,95,98,111,111,116,115,116,114,
+ 97,112,114,157,0,0,0,218,9,78,97,109,101,69,114,114,
+ 111,114,41,3,114,146,0,0,0,114,147,0,0,0,114,157,
+ 0,0,0,114,10,0,0,0,114,145,0,0,0,114,11,0,
+ 0,0,218,11,95,99,104,101,99,107,95,110,97,109,101,3,
+ 2,0,0,115,14,0,0,0,0,8,14,7,2,1,10,1,
+ 12,2,14,5,10,1,114,160,0,0,0,99,2,0,0,0,
+ 0,0,0,0,0,0,0,0,5,0,0,0,6,0,0,0,
+ 67,0,0,0,115,60,0,0,0,124,0,160,0,124,1,161,
+ 1,92,2,125,2,125,3,124,2,100,1,117,0,114,56,116,
+ 1,124,3,131,1,114,56,100,2,125,4,116,2,160,3,124,
+ 4,160,4,124,3,100,3,25,0,161,1,116,5,161,2,1,
+ 0,124,2,83,0,41,4,122,155,84,114,121,32,116,111,32,
+ 102,105,110,100,32,97,32,108,111,97,100,101,114,32,102,111,
+ 114,32,116,104,101,32,115,112,101,99,105,102,105,101,100,32,
+ 109,111,100,117,108,101,32,98,121,32,100,101,108,101,103,97,
+ 116,105,110,103,32,116,111,10,32,32,32,32,115,101,108,102,
+ 46,102,105,110,100,95,108,111,97,100,101,114,40,41,46,10,
+ 10,32,32,32,32,84,104,105,115,32,109,101,116,104,111,100,
+ 32,105,115,32,100,101,112,114,101,99,97,116,101,100,32,105,
+ 110,32,102,97,118,111,114,32,111,102,32,102,105,110,100,101,
+ 114,46,102,105,110,100,95,115,112,101,99,40,41,46,10,10,
+ 32,32,32,32,78,122,44,78,111,116,32,105,109,112,111,114,
+ 116,105,110,103,32,100,105,114,101,99,116,111,114,121,32,123,
+ 125,58,32,109,105,115,115,105,110,103,32,95,95,105,110,105,
+ 116,95,95,114,0,0,0,0,41,6,218,11,102,105,110,100,
+ 95,108,111,97,100,101,114,114,6,0,0,0,114,98,0,0,
+ 0,114,99,0,0,0,114,88,0,0,0,218,13,73,109,112,
+ 111,114,116,87,97,114,110,105,110,103,41,5,114,142,0,0,
+ 0,218,8,102,117,108,108,110,97,109,101,218,6,108,111,97,
+ 100,101,114,218,8,112,111,114,116,105,111,110,115,218,3,109,
+ 115,103,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+ 0,218,17,95,102,105,110,100,95,109,111,100,117,108,101,95,
+ 115,104,105,109,31,2,0,0,115,10,0,0,0,0,10,14,
+ 1,16,1,4,1,22,1,114,167,0,0,0,99,3,0,0,
+ 0,0,0,0,0,0,0,0,0,6,0,0,0,4,0,0,
+ 0,67,0,0,0,115,166,0,0,0,124,0,100,1,100,2,
+ 133,2,25,0,125,3,124,3,116,0,107,3,114,64,100,3,
+ 124,1,155,2,100,4,124,3,155,2,157,4,125,4,116,1,
+ 160,2,100,5,124,4,161,2,1,0,116,3,124,4,102,1,
+ 105,0,124,2,164,1,142,1,130,1,116,4,124,0,131,1,
+ 100,6,107,0,114,106,100,7,124,1,155,2,157,2,125,4,
+ 116,1,160,2,100,5,124,4,161,2,1,0,116,5,124,4,
+ 131,1,130,1,116,6,124,0,100,2,100,8,133,2,25,0,
+ 131,1,125,5,124,5,100,9,64,0,114,162,100,10,124,5,
+ 155,2,100,11,124,1,155,2,157,4,125,4,116,3,124,4,
+ 102,1,105,0,124,2,164,1,142,1,130,1,124,5,83,0,
+ 41,12,97,84,2,0,0,80,101,114,102,111,114,109,32,98,
+ 97,115,105,99,32,118,97,108,105,100,105,116,121,32,99,104,
+ 101,99,107,105,110,103,32,111,102,32,97,32,112,121,99,32,
+ 104,101,97,100,101,114,32,97,110,100,32,114,101,116,117,114,
+ 110,32,116,104,101,32,102,108,97,103,115,32,102,105,101,108,
+ 100,44,10,32,32,32,32,119,104,105,99,104,32,100,101,116,
+ 101,114,109,105,110,101,115,32,104,111,119,32,116,104,101,32,
+ 112,121,99,32,115,104,111,117,108,100,32,98,101,32,102,117,
+ 114,116,104,101,114,32,118,97,108,105,100,97,116,101,100,32,
+ 97,103,97,105,110,115,116,32,116,104,101,32,115,111,117,114,
+ 99,101,46,10,10,32,32,32,32,42,100,97,116,97,42,32,
+ 105,115,32,116,104,101,32,99,111,110,116,101,110,116,115,32,
+ 111,102,32,116,104,101,32,112,121,99,32,102,105,108,101,46,
+ 32,40,79,110,108,121,32,116,104,101,32,102,105,114,115,116,
+ 32,49,54,32,98,121,116,101,115,32,97,114,101,10,32,32,
+ 32,32,114,101,113,117,105,114,101,100,44,32,116,104,111,117,
+ 103,104,46,41,10,10,32,32,32,32,42,110,97,109,101,42,
+ 32,105,115,32,116,104,101,32,110,97,109,101,32,111,102,32,
+ 116,104,101,32,109,111,100,117,108,101,32,98,101,105,110,103,
+ 32,105,109,112,111,114,116,101,100,46,32,73,116,32,105,115,
+ 32,117,115,101,100,32,102,111,114,32,108,111,103,103,105,110,
+ 103,46,10,10,32,32,32,32,42,101,120,99,95,100,101,116,
+ 97,105,108,115,42,32,105,115,32,97,32,100,105,99,116,105,
+ 111,110,97,114,121,32,112,97,115,115,101,100,32,116,111,32,
+ 73,109,112,111,114,116,69,114,114,111,114,32,105,102,32,105,
+ 116,32,114,97,105,115,101,100,32,102,111,114,10,32,32,32,
+ 32,105,109,112,114,111,118,101,100,32,100,101,98,117,103,103,
+ 105,110,103,46,10,10,32,32,32,32,73,109,112,111,114,116,
+ 69,114,114,111,114,32,105,115,32,114,97,105,115,101,100,32,
+ 119,104,101,110,32,116,104,101,32,109,97,103,105,99,32,110,
+ 117,109,98,101,114,32,105,115,32,105,110,99,111,114,114,101,
+ 99,116,32,111,114,32,119,104,101,110,32,116,104,101,32,102,
+ 108,97,103,115,10,32,32,32,32,102,105,101,108,100,32,105,
+ 115,32,105,110,118,97,108,105,100,46,32,69,79,70,69,114,
+ 114,111,114,32,105,115,32,114,97,105,115,101,100,32,119,104,
+ 101,110,32,116,104,101,32,100,97,116,97,32,105,115,32,102,
+ 111,117,110,100,32,116,111,32,98,101,32,116,114,117,110,99,
+ 97,116,101,100,46,10,10,32,32,32,32,78,114,34,0,0,
+ 0,122,20,98,97,100,32,109,97,103,105,99,32,110,117,109,
+ 98,101,114,32,105,110,32,122,2,58,32,250,2,123,125,233,
+ 16,0,0,0,122,40,114,101,97,99,104,101,100,32,69,79,
+ 70,32,119,104,105,108,101,32,114,101,97,100,105,110,103,32,
+ 112,121,99,32,104,101,97,100,101,114,32,111,102,32,233,8,
+ 0,0,0,233,252,255,255,255,122,14,105,110,118,97,108,105,
+ 100,32,102,108,97,103,115,32,122,4,32,105,110,32,41,7,
+ 218,12,77,65,71,73,67,95,78,85,77,66,69,82,114,158,
+ 0,0,0,218,16,95,118,101,114,98,111,115,101,95,109,101,
+ 115,115,97,103,101,114,141,0,0,0,114,6,0,0,0,218,
+ 8,69,79,70,69,114,114,111,114,114,44,0,0,0,41,6,
+ 114,43,0,0,0,114,140,0,0,0,218,11,101,120,99,95,
+ 100,101,116,97,105,108,115,90,5,109,97,103,105,99,114,116,
+ 0,0,0,114,22,0,0,0,114,10,0,0,0,114,10,0,
+ 0,0,114,11,0,0,0,218,13,95,99,108,97,115,115,105,
+ 102,121,95,112,121,99,48,2,0,0,115,28,0,0,0,0,
+ 16,12,1,8,1,16,1,12,1,16,1,12,1,10,1,12,
+ 1,8,1,16,2,8,1,16,1,16,1,114,176,0,0,0,
+ 99,5,0,0,0,0,0,0,0,0,0,0,0,6,0,0,
+ 0,4,0,0,0,67,0,0,0,115,120,0,0,0,116,0,
+ 124,0,100,1,100,2,133,2,25,0,131,1,124,1,100,3,
+ 64,0,107,3,114,62,100,4,124,3,155,2,157,2,125,5,
+ 116,1,160,2,100,5,124,5,161,2,1,0,116,3,124,5,
+ 102,1,105,0,124,4,164,1,142,1,130,1,124,2,100,6,
+ 117,1,114,116,116,0,124,0,100,2,100,7,133,2,25,0,
+ 131,1,124,2,100,3,64,0,107,3,114,116,116,3,100,4,
+ 124,3,155,2,157,2,102,1,105,0,124,4,164,1,142,1,
+ 130,1,100,6,83,0,41,8,97,7,2,0,0,86,97,108,
+ 105,100,97,116,101,32,97,32,112,121,99,32,97,103,97,105,
+ 110,115,116,32,116,104,101,32,115,111,117,114,99,101,32,108,
+ 97,115,116,45,109,111,100,105,102,105,101,100,32,116,105,109,
+ 101,46,10,10,32,32,32,32,42,100,97,116,97,42,32,105,
+ 115,32,116,104,101,32,99,111,110,116,101,110,116,115,32,111,
+ 102,32,116,104,101,32,112,121,99,32,102,105,108,101,46,32,
+ 40,79,110,108,121,32,116,104,101,32,102,105,114,115,116,32,
+ 49,54,32,98,121,116,101,115,32,97,114,101,10,32,32,32,
+ 32,114,101,113,117,105,114,101,100,46,41,10,10,32,32,32,
+ 32,42,115,111,117,114,99,101,95,109,116,105,109,101,42,32,
+ 105,115,32,116,104,101,32,108,97,115,116,32,109,111,100,105,
+ 102,105,101,100,32,116,105,109,101,115,116,97,109,112,32,111,
+ 102,32,116,104,101,32,115,111,117,114,99,101,32,102,105,108,
+ 101,46,10,10,32,32,32,32,42,115,111,117,114,99,101,95,
+ 115,105,122,101,42,32,105,115,32,78,111,110,101,32,111,114,
+ 32,116,104,101,32,115,105,122,101,32,111,102,32,116,104,101,
+ 32,115,111,117,114,99,101,32,102,105,108,101,32,105,110,32,
+ 98,121,116,101,115,46,10,10,32,32,32,32,42,110,97,109,
+ 101,42,32,105,115,32,116,104,101,32,110,97,109,101,32,111,
+ 102,32,116,104,101,32,109,111,100,117,108,101,32,98,101,105,
+ 110,103,32,105,109,112,111,114,116,101,100,46,32,73,116,32,
+ 105,115,32,117,115,101,100,32,102,111,114,32,108,111,103,103,
+ 105,110,103,46,10,10,32,32,32,32,42,101,120,99,95,100,
+ 101,116,97,105,108,115,42,32,105,115,32,97,32,100,105,99,
+ 116,105,111,110,97,114,121,32,112,97,115,115,101,100,32,116,
+ 111,32,73,109,112,111,114,116,69,114,114,111,114,32,105,102,
+ 32,105,116,32,114,97,105,115,101,100,32,102,111,114,10,32,
+ 32,32,32,105,109,112,114,111,118,101,100,32,100,101,98,117,
+ 103,103,105,110,103,46,10,10,32,32,32,32,65,110,32,73,
+ 109,112,111,114,116,69,114,114,111,114,32,105,115,32,114,97,
+ 105,115,101,100,32,105,102,32,116,104,101,32,98,121,116,101,
+ 99,111,100,101,32,105,115,32,115,116,97,108,101,46,10,10,
+ 32,32,32,32,114,170,0,0,0,233,12,0,0,0,114,33,
+ 0,0,0,122,22,98,121,116,101,99,111,100,101,32,105,115,
+ 32,115,116,97,108,101,32,102,111,114,32,114,168,0,0,0,
+ 78,114,169,0,0,0,41,4,114,44,0,0,0,114,158,0,
+ 0,0,114,173,0,0,0,114,141,0,0,0,41,6,114,43,
+ 0,0,0,218,12,115,111,117,114,99,101,95,109,116,105,109,
+ 101,218,11,115,111,117,114,99,101,95,115,105,122,101,114,140,
+ 0,0,0,114,175,0,0,0,114,116,0,0,0,114,10,0,
+ 0,0,114,10,0,0,0,114,11,0,0,0,218,23,95,118,
+ 97,108,105,100,97,116,101,95,116,105,109,101,115,116,97,109,
+ 112,95,112,121,99,81,2,0,0,115,16,0,0,0,0,19,
+ 24,1,10,1,12,1,16,1,8,1,22,255,2,2,114,180,
+ 0,0,0,99,4,0,0,0,0,0,0,0,0,0,0,0,
+ 4,0,0,0,4,0,0,0,67,0,0,0,115,42,0,0,
+ 0,124,0,100,1,100,2,133,2,25,0,124,1,107,3,114,
+ 38,116,0,100,3,124,2,155,2,157,2,102,1,105,0,124,
+ 3,164,1,142,1,130,1,100,4,83,0,41,5,97,243,1,
+ 0,0,86,97,108,105,100,97,116,101,32,97,32,104,97,115,
+ 104,45,98,97,115,101,100,32,112,121,99,32,98,121,32,99,
+ 104,101,99,107,105,110,103,32,116,104,101,32,114,101,97,108,
+ 32,115,111,117,114,99,101,32,104,97,115,104,32,97,103,97,
+ 105,110,115,116,32,116,104,101,32,111,110,101,32,105,110,10,
+ 32,32,32,32,116,104,101,32,112,121,99,32,104,101,97,100,
+ 101,114,46,10,10,32,32,32,32,42,100,97,116,97,42,32,
+ 105,115,32,116,104,101,32,99,111,110,116,101,110,116,115,32,
+ 111,102,32,116,104,101,32,112,121,99,32,102,105,108,101,46,
+ 32,40,79,110,108,121,32,116,104,101,32,102,105,114,115,116,
+ 32,49,54,32,98,121,116,101,115,32,97,114,101,10,32,32,
+ 32,32,114,101,113,117,105,114,101,100,46,41,10,10,32,32,
+ 32,32,42,115,111,117,114,99,101,95,104,97,115,104,42,32,
+ 105,115,32,116,104,101,32,105,109,112,111,114,116,108,105,98,
+ 46,117,116,105,108,46,115,111,117,114,99,101,95,104,97,115,
+ 104,40,41,32,111,102,32,116,104,101,32,115,111,117,114,99,
+ 101,32,102,105,108,101,46,10,10,32,32,32,32,42,110,97,
+ 109,101,42,32,105,115,32,116,104,101,32,110,97,109,101,32,
+ 111,102,32,116,104,101,32,109,111,100,117,108,101,32,98,101,
+ 105,110,103,32,105,109,112,111,114,116,101,100,46,32,73,116,
+ 32,105,115,32,117,115,101,100,32,102,111,114,32,108,111,103,
+ 103,105,110,103,46,10,10,32,32,32,32,42,101,120,99,95,
+ 100,101,116,97,105,108,115,42,32,105,115,32,97,32,100,105,
+ 99,116,105,111,110,97,114,121,32,112,97,115,115,101,100,32,
+ 116,111,32,73,109,112,111,114,116,69,114,114,111,114,32,105,
+ 102,32,105,116,32,114,97,105,115,101,100,32,102,111,114,10,
+ 32,32,32,32,105,109,112,114,111,118,101,100,32,100,101,98,
+ 117,103,103,105,110,103,46,10,10,32,32,32,32,65,110,32,
+ 73,109,112,111,114,116,69,114,114,111,114,32,105,115,32,114,
+ 97,105,115,101,100,32,105,102,32,116,104,101,32,98,121,116,
+ 101,99,111,100,101,32,105,115,32,115,116,97,108,101,46,10,
+ 10,32,32,32,32,114,170,0,0,0,114,169,0,0,0,122,
+ 46,104,97,115,104,32,105,110,32,98,121,116,101,99,111,100,
+ 101,32,100,111,101,115,110,39,116,32,109,97,116,99,104,32,
+ 104,97,115,104,32,111,102,32,115,111,117,114,99,101,32,78,
+ 41,1,114,141,0,0,0,41,4,114,43,0,0,0,218,11,
+ 115,111,117,114,99,101,95,104,97,115,104,114,140,0,0,0,
+ 114,175,0,0,0,114,10,0,0,0,114,10,0,0,0,114,
+ 11,0,0,0,218,18,95,118,97,108,105,100,97,116,101,95,
+ 104,97,115,104,95,112,121,99,109,2,0,0,115,12,0,0,
+ 0,0,17,16,1,2,1,8,255,4,2,2,254,114,182,0,
+ 0,0,99,4,0,0,0,0,0,0,0,0,0,0,0,5,
+ 0,0,0,5,0,0,0,67,0,0,0,115,80,0,0,0,
+ 116,0,160,1,124,0,161,1,125,4,116,2,124,4,116,3,
+ 131,2,114,56,116,4,160,5,100,1,124,2,161,2,1,0,
+ 124,3,100,2,117,1,114,52,116,6,160,7,124,4,124,3,
+ 161,2,1,0,124,4,83,0,116,8,100,3,160,9,124,2,
+ 161,1,124,1,124,2,100,4,141,3,130,1,100,2,83,0,
+ 41,5,122,35,67,111,109,112,105,108,101,32,98,121,116,101,
+ 99,111,100,101,32,97,115,32,102,111,117,110,100,32,105,110,
+ 32,97,32,112,121,99,46,122,21,99,111,100,101,32,111,98,
+ 106,101,99,116,32,102,114,111,109,32,123,33,114,125,78,122,
+ 23,78,111,110,45,99,111,100,101,32,111,98,106,101,99,116,
+ 32,105,110,32,123,33,114,125,169,2,114,140,0,0,0,114,
+ 65,0,0,0,41,10,218,7,109,97,114,115,104,97,108,90,
+ 5,108,111,97,100,115,218,10,105,115,105,110,115,116,97,110,
+ 99,101,218,10,95,99,111,100,101,95,116,121,112,101,114,158,
+ 0,0,0,114,173,0,0,0,218,4,95,105,109,112,90,16,
+ 95,102,105,120,95,99,111,95,102,105,108,101,110,97,109,101,
+ 114,141,0,0,0,114,88,0,0,0,41,5,114,43,0,0,
+ 0,114,140,0,0,0,114,131,0,0,0,114,133,0,0,0,
+ 218,4,99,111,100,101,114,10,0,0,0,114,10,0,0,0,
+ 114,11,0,0,0,218,17,95,99,111,109,112,105,108,101,95,
+ 98,121,116,101,99,111,100,101,133,2,0,0,115,18,0,0,
+ 0,0,2,10,1,10,1,12,1,8,1,12,1,4,2,10,
+ 1,4,255,114,189,0,0,0,99,3,0,0,0,0,0,0,
+ 0,0,0,0,0,4,0,0,0,5,0,0,0,67,0,0,
+ 0,115,70,0,0,0,116,0,116,1,131,1,125,3,124,3,
+ 160,2,116,3,100,1,131,1,161,1,1,0,124,3,160,2,
+ 116,3,124,1,131,1,161,1,1,0,124,3,160,2,116,3,
+ 124,2,131,1,161,1,1,0,124,3,160,2,116,4,160,5,
+ 124,0,161,1,161,1,1,0,124,3,83,0,41,2,122,43,
+ 80,114,111,100,117,99,101,32,116,104,101,32,100,97,116,97,
+ 32,102,111,114,32,97,32,116,105,109,101,115,116,97,109,112,
+ 45,98,97,115,101,100,32,112,121,99,46,114,0,0,0,0,
+ 41,6,218,9,98,121,116,101,97,114,114,97,121,114,172,0,
+ 0,0,218,6,101,120,116,101,110,100,114,39,0,0,0,114,
+ 184,0,0,0,218,5,100,117,109,112,115,41,4,114,188,0,
+ 0,0,218,5,109,116,105,109,101,114,179,0,0,0,114,43,
+ 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,
+ 0,0,218,22,95,99,111,100,101,95,116,111,95,116,105,109,
+ 101,115,116,97,109,112,95,112,121,99,146,2,0,0,115,12,
+ 0,0,0,0,2,8,1,14,1,14,1,14,1,16,1,114,
+ 194,0,0,0,84,99,3,0,0,0,0,0,0,0,0,0,
+ 0,0,5,0,0,0,5,0,0,0,67,0,0,0,115,80,
+ 0,0,0,116,0,116,1,131,1,125,3,100,1,124,2,100,
+ 1,62,0,66,0,125,4,124,3,160,2,116,3,124,4,131,
+ 1,161,1,1,0,116,4,124,1,131,1,100,2,107,2,115,
+ 50,74,0,130,1,124,3,160,2,124,1,161,1,1,0,124,
+ 3,160,2,116,5,160,6,124,0,161,1,161,1,1,0,124,
+ 3,83,0,41,3,122,38,80,114,111,100,117,99,101,32,116,
+ 104,101,32,100,97,116,97,32,102,111,114,32,97,32,104,97,
+ 115,104,45,98,97,115,101,100,32,112,121,99,46,114,4,0,
+ 0,0,114,170,0,0,0,41,7,114,190,0,0,0,114,172,
+ 0,0,0,114,191,0,0,0,114,39,0,0,0,114,6,0,
+ 0,0,114,184,0,0,0,114,192,0,0,0,41,5,114,188,
+ 0,0,0,114,181,0,0,0,90,7,99,104,101,99,107,101,
+ 100,114,43,0,0,0,114,22,0,0,0,114,10,0,0,0,
+ 114,10,0,0,0,114,11,0,0,0,218,17,95,99,111,100,
+ 101,95,116,111,95,104,97,115,104,95,112,121,99,156,2,0,
+ 0,115,14,0,0,0,0,2,8,1,12,1,14,1,16,1,
+ 10,1,16,1,114,195,0,0,0,99,1,0,0,0,0,0,
+ 0,0,0,0,0,0,5,0,0,0,6,0,0,0,67,0,
+ 0,0,115,62,0,0,0,100,1,100,2,108,0,125,1,116,
+ 1,160,2,124,0,161,1,106,3,125,2,124,1,160,4,124,
+ 2,161,1,125,3,116,1,160,5,100,2,100,3,161,2,125,
+ 4,124,4,160,6,124,0,160,6,124,3,100,1,25,0,161,
+ 1,161,1,83,0,41,4,122,121,68,101,99,111,100,101,32,
+ 98,121,116,101,115,32,114,101,112,114,101,115,101,110,116,105,
+ 110,103,32,115,111,117,114,99,101,32,99,111,100,101,32,97,
+ 110,100,32,114,101,116,117,114,110,32,116,104,101,32,115,116,
+ 114,105,110,103,46,10,10,32,32,32,32,85,110,105,118,101,
+ 114,115,97,108,32,110,101,119,108,105,110,101,32,115,117,112,
+ 112,111,114,116,32,105,115,32,117,115,101,100,32,105,110,32,
+ 116,104,101,32,100,101,99,111,100,105,110,103,46,10,32,32,
+ 32,32,114,0,0,0,0,78,84,41,7,218,8,116,111,107,
+ 101,110,105,122,101,114,90,0,0,0,90,7,66,121,116,101,
+ 115,73,79,90,8,114,101,97,100,108,105,110,101,90,15,100,
+ 101,116,101,99,116,95,101,110,99,111,100,105,110,103,90,25,
+ 73,110,99,114,101,109,101,110,116,97,108,78,101,119,108,105,
+ 110,101,68,101,99,111,100,101,114,218,6,100,101,99,111,100,
+ 101,41,5,218,12,115,111,117,114,99,101,95,98,121,116,101,
+ 115,114,196,0,0,0,90,21,115,111,117,114,99,101,95,98,
+ 121,116,101,115,95,114,101,97,100,108,105,110,101,218,8,101,
+ 110,99,111,100,105,110,103,90,15,110,101,119,108,105,110,101,
+ 95,100,101,99,111,100,101,114,114,10,0,0,0,114,10,0,
+ 0,0,114,11,0,0,0,218,13,100,101,99,111,100,101,95,
+ 115,111,117,114,99,101,167,2,0,0,115,10,0,0,0,0,
+ 5,8,1,12,1,10,1,12,1,114,200,0,0,0,169,2,
+ 114,164,0,0,0,218,26,115,117,98,109,111,100,117,108,101,
+ 95,115,101,97,114,99,104,95,108,111,99,97,116,105,111,110,
+ 115,99,2,0,0,0,0,0,0,0,2,0,0,0,9,0,
+ 0,0,8,0,0,0,67,0,0,0,115,12,1,0,0,124,
+ 1,100,1,117,0,114,58,100,2,125,1,116,0,124,2,100,
+ 3,131,2,114,68,122,14,124,2,160,1,124,0,161,1,125,
+ 1,87,0,113,68,4,0,116,2,121,54,1,0,1,0,1,
+ 0,89,0,113,68,48,0,110,10,116,3,160,4,124,1,161,
+ 1,125,1,116,5,106,6,124,0,124,2,124,1,100,4,141,
+ 3,125,4,100,5,124,4,95,7,124,2,100,1,117,0,114,
+ 152,116,8,131,0,68,0,93,42,92,2,125,5,125,6,124,
+ 1,160,9,116,10,124,6,131,1,161,1,114,104,124,5,124,
+ 0,124,1,131,2,125,2,124,2,124,4,95,11,1,0,113,
+ 152,113,104,100,1,83,0,124,3,116,12,117,0,114,216,116,
+ 0,124,2,100,6,131,2,114,222,122,14,124,2,160,13,124,
+ 0,161,1,125,7,87,0,110,18,4,0,116,2,121,202,1,
+ 0,1,0,1,0,89,0,113,222,48,0,124,7,114,222,103,
+ 0,124,4,95,14,110,6,124,3,124,4,95,14,124,4,106,
+ 14,103,0,107,2,144,1,114,8,124,1,144,1,114,8,116,
+ 15,124,1,131,1,100,7,25,0,125,8,124,4,106,14,160,
+ 16,124,8,161,1,1,0,124,4,83,0,41,8,97,61,1,
+ 0,0,82,101,116,117,114,110,32,97,32,109,111,100,117,108,
+ 101,32,115,112,101,99,32,98,97,115,101,100,32,111,110,32,
+ 97,32,102,105,108,101,32,108,111,99,97,116,105,111,110,46,
+ 10,10,32,32,32,32,84,111,32,105,110,100,105,99,97,116,
+ 101,32,116,104,97,116,32,116,104,101,32,109,111,100,117,108,
+ 101,32,105,115,32,97,32,112,97,99,107,97,103,101,44,32,
+ 115,101,116,10,32,32,32,32,115,117,98,109,111,100,117,108,
+ 101,95,115,101,97,114,99,104,95,108,111,99,97,116,105,111,
+ 110,115,32,116,111,32,97,32,108,105,115,116,32,111,102,32,
+ 100,105,114,101,99,116,111,114,121,32,112,97,116,104,115,46,
+ 32,32,65,110,10,32,32,32,32,101,109,112,116,121,32,108,
+ 105,115,116,32,105,115,32,115,117,102,102,105,99,105,101,110,
+ 116,44,32,116,104,111,117,103,104,32,105,116,115,32,110,111,
+ 116,32,111,116,104,101,114,119,105,115,101,32,117,115,101,102,
+ 117,108,32,116,111,32,116,104,101,10,32,32,32,32,105,109,
+ 112,111,114,116,32,115,121,115,116,101,109,46,10,10,32,32,
+ 32,32,84,104,101,32,108,111,97,100,101,114,32,109,117,115,
+ 116,32,116,97,107,101,32,97,32,115,112,101,99,32,97,115,
+ 32,105,116,115,32,111,110,108,121,32,95,95,105,110,105,116,
+ 95,95,40,41,32,97,114,103,46,10,10,32,32,32,32,78,
+ 122,9,60,117,110,107,110,111,119,110,62,218,12,103,101,116,
+ 95,102,105,108,101,110,97,109,101,169,1,218,6,111,114,105,
+ 103,105,110,84,218,10,105,115,95,112,97,99,107,97,103,101,
+ 114,0,0,0,0,41,17,114,152,0,0,0,114,203,0,0,
+ 0,114,141,0,0,0,114,24,0,0,0,114,102,0,0,0,
+ 114,158,0,0,0,218,10,77,111,100,117,108,101,83,112,101,
+ 99,90,13,95,115,101,116,95,102,105,108,101,97,116,116,114,
+ 218,27,95,103,101,116,95,115,117,112,112,111,114,116,101,100,
+ 95,102,105,108,101,95,108,111,97,100,101,114,115,114,58,0,
+ 0,0,114,135,0,0,0,114,164,0,0,0,218,9,95,80,
+ 79,80,85,76,65,84,69,114,206,0,0,0,114,202,0,0,
+ 0,114,74,0,0,0,114,61,0,0,0,41,9,114,140,0,
+ 0,0,90,8,108,111,99,97,116,105,111,110,114,164,0,0,
+ 0,114,202,0,0,0,218,4,115,112,101,99,218,12,108,111,
+ 97,100,101,114,95,99,108,97,115,115,218,8,115,117,102,102,
+ 105,120,101,115,114,206,0,0,0,90,7,100,105,114,110,97,
+ 109,101,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+ 0,218,23,115,112,101,99,95,102,114,111,109,95,102,105,108,
+ 101,95,108,111,99,97,116,105,111,110,184,2,0,0,115,62,
+ 0,0,0,0,12,8,4,4,1,10,2,2,1,14,1,12,
+ 1,8,2,10,8,16,1,6,3,8,1,14,1,14,1,10,
+ 1,6,1,6,2,4,3,8,2,10,1,2,1,14,1,12,
+ 1,6,2,4,1,8,2,6,1,12,1,6,1,12,1,12,
+ 2,114,213,0,0,0,99,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,4,0,0,0,64,0,0,0,115,
+ 80,0,0,0,101,0,90,1,100,0,90,2,100,1,90,3,
+ 100,2,90,4,100,3,90,5,100,4,90,6,101,7,100,5,
+ 100,6,132,0,131,1,90,8,101,7,100,7,100,8,132,0,
+ 131,1,90,9,101,7,100,14,100,10,100,11,132,1,131,1,
+ 90,10,101,7,100,15,100,12,100,13,132,1,131,1,90,11,
+ 100,9,83,0,41,16,218,21,87,105,110,100,111,119,115,82,
+ 101,103,105,115,116,114,121,70,105,110,100,101,114,122,62,77,
+ 101,116,97,32,112,97,116,104,32,102,105,110,100,101,114,32,
+ 102,111,114,32,109,111,100,117,108,101,115,32,100,101,99,108,
+ 97,114,101,100,32,105,110,32,116,104,101,32,87,105,110,100,
+ 111,119,115,32,114,101,103,105,115,116,114,121,46,122,59,83,
+ 111,102,116,119,97,114,101,92,80,121,116,104,111,110,92,80,
+ 121,116,104,111,110,67,111,114,101,92,123,115,121,115,95,118,
+ 101,114,115,105,111,110,125,92,77,111,100,117,108,101,115,92,
+ 123,102,117,108,108,110,97,109,101,125,122,65,83,111,102,116,
+ 119,97,114,101,92,80,121,116,104,111,110,92,80,121,116,104,
+ 111,110,67,111,114,101,92,123,115,121,115,95,118,101,114,115,
+ 105,111,110,125,92,77,111,100,117,108,101,115,92,123,102,117,
+ 108,108,110,97,109,101,125,92,68,101,98,117,103,70,99,2,
+ 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,8,
+ 0,0,0,67,0,0,0,115,54,0,0,0,122,16,116,0,
+ 160,1,116,0,106,2,124,1,161,2,87,0,83,0,4,0,
+ 116,3,121,48,1,0,1,0,1,0,116,0,160,1,116,0,
+ 106,4,124,1,161,2,6,0,89,0,83,0,48,0,100,0,
+ 83,0,114,69,0,0,0,41,5,218,6,119,105,110,114,101,
+ 103,90,7,79,112,101,110,75,101,121,90,17,72,75,69,89,
+ 95,67,85,82,82,69,78,84,95,85,83,69,82,114,76,0,
+ 0,0,90,18,72,75,69,89,95,76,79,67,65,76,95,77,
+ 65,67,72,73,78,69,41,2,218,3,99,108,115,114,26,0,
+ 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+ 0,218,14,95,111,112,101,110,95,114,101,103,105,115,116,114,
+ 121,8,3,0,0,115,8,0,0,0,0,2,2,1,16,1,
+ 12,1,122,36,87,105,110,100,111,119,115,82,101,103,105,115,
+ 116,114,121,70,105,110,100,101,114,46,95,111,112,101,110,95,
+ 114,101,103,105,115,116,114,121,99,2,0,0,0,0,0,0,
+ 0,0,0,0,0,6,0,0,0,8,0,0,0,67,0,0,
+ 0,115,132,0,0,0,124,0,106,0,114,14,124,0,106,1,
+ 125,2,110,6,124,0,106,2,125,2,124,2,106,3,124,1,
+ 100,1,116,4,106,5,100,0,100,2,133,2,25,0,22,0,
+ 100,3,141,2,125,3,122,58,124,0,160,6,124,3,161,1,
+ 143,28,125,4,116,7,160,8,124,4,100,4,161,2,125,5,
+ 87,0,100,0,4,0,4,0,131,3,1,0,110,16,49,0,
+ 115,94,48,0,1,0,1,0,1,0,89,0,1,0,87,0,
+ 110,20,4,0,116,9,121,126,1,0,1,0,1,0,89,0,
+ 100,0,83,0,48,0,124,5,83,0,41,5,78,122,5,37,
+ 100,46,37,100,114,45,0,0,0,41,2,114,163,0,0,0,
+ 90,11,115,121,115,95,118,101,114,115,105,111,110,114,14,0,
+ 0,0,41,10,218,11,68,69,66,85,71,95,66,85,73,76,
+ 68,218,18,82,69,71,73,83,84,82,89,95,75,69,89,95,
+ 68,69,66,85,71,218,12,82,69,71,73,83,84,82,89,95,
+ 75,69,89,114,88,0,0,0,114,21,0,0,0,218,12,118,
+ 101,114,115,105,111,110,95,105,110,102,111,114,217,0,0,0,
+ 114,215,0,0,0,90,10,81,117,101,114,121,86,97,108,117,
+ 101,114,76,0,0,0,41,6,114,216,0,0,0,114,163,0,
+ 0,0,90,12,114,101,103,105,115,116,114,121,95,107,101,121,
+ 114,26,0,0,0,90,4,104,107,101,121,218,8,102,105,108,
+ 101,112,97,116,104,114,10,0,0,0,114,10,0,0,0,114,
+ 11,0,0,0,218,16,95,115,101,97,114,99,104,95,114,101,
+ 103,105,115,116,114,121,15,3,0,0,115,24,0,0,0,0,
+ 2,6,1,8,2,6,1,6,1,16,255,6,2,2,1,12,
+ 1,46,1,12,1,8,1,122,38,87,105,110,100,111,119,115,
+ 82,101,103,105,115,116,114,121,70,105,110,100,101,114,46,95,
+ 115,101,97,114,99,104,95,114,101,103,105,115,116,114,121,78,
+ 99,4,0,0,0,0,0,0,0,0,0,0,0,8,0,0,
+ 0,8,0,0,0,67,0,0,0,115,120,0,0,0,124,0,
+ 160,0,124,1,161,1,125,4,124,4,100,0,117,0,114,22,
+ 100,0,83,0,122,12,116,1,124,4,131,1,1,0,87,0,
+ 110,20,4,0,116,2,121,54,1,0,1,0,1,0,89,0,
+ 100,0,83,0,48,0,116,3,131,0,68,0,93,52,92,2,
+ 125,5,125,6,124,4,160,4,116,5,124,6,131,1,161,1,
+ 114,62,116,6,106,7,124,1,124,5,124,1,124,4,131,2,
+ 124,4,100,1,141,3,125,7,124,7,2,0,1,0,83,0,
+ 113,62,100,0,83,0,41,2,78,114,204,0,0,0,41,8,
+ 114,223,0,0,0,114,75,0,0,0,114,76,0,0,0,114,
+ 208,0,0,0,114,58,0,0,0,114,135,0,0,0,114,158,
+ 0,0,0,218,16,115,112,101,99,95,102,114,111,109,95,108,
+ 111,97,100,101,114,41,8,114,216,0,0,0,114,163,0,0,
+ 0,114,65,0,0,0,218,6,116,97,114,103,101,116,114,222,
+ 0,0,0,114,164,0,0,0,114,212,0,0,0,114,210,0,
+ 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+ 0,218,9,102,105,110,100,95,115,112,101,99,30,3,0,0,
+ 115,28,0,0,0,0,2,10,1,8,1,4,1,2,1,12,
+ 1,12,1,8,1,14,1,14,1,6,1,8,1,2,254,6,
+ 3,122,31,87,105,110,100,111,119,115,82,101,103,105,115,116,
+ 114,121,70,105,110,100,101,114,46,102,105,110,100,95,115,112,
+ 101,99,99,3,0,0,0,0,0,0,0,0,0,0,0,4,
+ 0,0,0,4,0,0,0,67,0,0,0,115,34,0,0,0,
+ 124,0,160,0,124,1,124,2,161,2,125,3,124,3,100,1,
+ 117,1,114,26,124,3,106,1,83,0,100,1,83,0,100,1,
+ 83,0,41,2,122,108,70,105,110,100,32,109,111,100,117,108,
+ 101,32,110,97,109,101,100,32,105,110,32,116,104,101,32,114,
+ 101,103,105,115,116,114,121,46,10,10,32,32,32,32,32,32,
+ 32,32,84,104,105,115,32,109,101,116,104,111,100,32,105,115,
+ 32,100,101,112,114,101,99,97,116,101,100,46,32,32,85,115,
+ 101,32,101,120,101,99,95,109,111,100,117,108,101,40,41,32,
+ 105,110,115,116,101,97,100,46,10,10,32,32,32,32,32,32,
+ 32,32,78,169,2,114,226,0,0,0,114,164,0,0,0,169,
+ 4,114,216,0,0,0,114,163,0,0,0,114,65,0,0,0,
+ 114,210,0,0,0,114,10,0,0,0,114,10,0,0,0,114,
+ 11,0,0,0,218,11,102,105,110,100,95,109,111,100,117,108,
+ 101,46,3,0,0,115,8,0,0,0,0,7,12,1,8,1,
+ 6,2,122,33,87,105,110,100,111,119,115,82,101,103,105,115,
+ 116,114,121,70,105,110,100,101,114,46,102,105,110,100,95,109,
+ 111,100,117,108,101,41,2,78,78,41,1,78,41,12,114,149,
+ 0,0,0,114,148,0,0,0,114,150,0,0,0,114,151,0,
+ 0,0,114,220,0,0,0,114,219,0,0,0,114,218,0,0,
+ 0,218,11,99,108,97,115,115,109,101,116,104,111,100,114,217,
+ 0,0,0,114,223,0,0,0,114,226,0,0,0,114,229,0,
+ 0,0,114,10,0,0,0,114,10,0,0,0,114,10,0,0,
+ 0,114,11,0,0,0,114,214,0,0,0,252,2,0,0,115,
+ 28,0,0,0,8,2,4,3,2,255,2,4,2,255,2,3,
+ 4,2,2,1,10,6,2,1,10,14,2,1,12,15,2,1,
+ 114,214,0,0,0,99,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,2,0,0,0,64,0,0,0,115,48,
+ 0,0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,
+ 2,100,3,132,0,90,4,100,4,100,5,132,0,90,5,100,
+ 6,100,7,132,0,90,6,100,8,100,9,132,0,90,7,100,
+ 10,83,0,41,11,218,13,95,76,111,97,100,101,114,66,97,
+ 115,105,99,115,122,83,66,97,115,101,32,99,108,97,115,115,
+ 32,111,102,32,99,111,109,109,111,110,32,99,111,100,101,32,
+ 110,101,101,100,101,100,32,98,121,32,98,111,116,104,32,83,
+ 111,117,114,99,101,76,111,97,100,101,114,32,97,110,100,10,
+ 32,32,32,32,83,111,117,114,99,101,108,101,115,115,70,105,
+ 108,101,76,111,97,100,101,114,46,99,2,0,0,0,0,0,
+ 0,0,0,0,0,0,5,0,0,0,4,0,0,0,67,0,
+ 0,0,115,64,0,0,0,116,0,124,0,160,1,124,1,161,
+ 1,131,1,100,1,25,0,125,2,124,2,160,2,100,2,100,
+ 1,161,2,100,3,25,0,125,3,124,1,160,3,100,2,161,
+ 1,100,4,25,0,125,4,124,3,100,5,107,2,111,62,124,
+ 4,100,5,107,3,83,0,41,6,122,141,67,111,110,99,114,
+ 101,116,101,32,105,109,112,108,101,109,101,110,116,97,116,105,
+ 111,110,32,111,102,32,73,110,115,112,101,99,116,76,111,97,
+ 100,101,114,46,105,115,95,112,97,99,107,97,103,101,32,98,
+ 121,32,99,104,101,99,107,105,110,103,32,105,102,10,32,32,
+ 32,32,32,32,32,32,116,104,101,32,112,97,116,104,32,114,
+ 101,116,117,114,110,101,100,32,98,121,32,103,101,116,95,102,
+ 105,108,101,110,97,109,101,32,104,97,115,32,97,32,102,105,
+ 108,101,110,97,109,101,32,111,102,32,39,95,95,105,110,105,
+ 116,95,95,46,112,121,39,46,114,4,0,0,0,114,96,0,
+ 0,0,114,0,0,0,0,114,45,0,0,0,218,8,95,95,
+ 105,110,105,116,95,95,41,4,114,74,0,0,0,114,203,0,
+ 0,0,114,124,0,0,0,114,103,0,0,0,41,5,114,142,
+ 0,0,0,114,163,0,0,0,114,119,0,0,0,90,13,102,
+ 105,108,101,110,97,109,101,95,98,97,115,101,90,9,116,97,
+ 105,108,95,110,97,109,101,114,10,0,0,0,114,10,0,0,
+ 0,114,11,0,0,0,114,206,0,0,0,65,3,0,0,115,
+ 8,0,0,0,0,3,18,1,16,1,14,1,122,24,95,76,
+ 111,97,100,101,114,66,97,115,105,99,115,46,105,115,95,112,
+ 97,99,107,97,103,101,99,2,0,0,0,0,0,0,0,0,
+ 0,0,0,2,0,0,0,1,0,0,0,67,0,0,0,115,
+ 4,0,0,0,100,1,83,0,169,2,122,42,85,115,101,32,
+ 100,101,102,97,117,108,116,32,115,101,109,97,110,116,105,99,
+ 115,32,102,111,114,32,109,111,100,117,108,101,32,99,114,101,
+ 97,116,105,111,110,46,78,114,10,0,0,0,169,2,114,142,
+ 0,0,0,114,210,0,0,0,114,10,0,0,0,114,10,0,
+ 0,0,114,11,0,0,0,218,13,99,114,101,97,116,101,95,
+ 109,111,100,117,108,101,73,3,0,0,115,2,0,0,0,0,
+ 1,122,27,95,76,111,97,100,101,114,66,97,115,105,99,115,
+ 46,99,114,101,97,116,101,95,109,111,100,117,108,101,99,2,
+ 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,5,
+ 0,0,0,67,0,0,0,115,56,0,0,0,124,0,160,0,
+ 124,1,106,1,161,1,125,2,124,2,100,1,117,0,114,36,
+ 116,2,100,2,160,3,124,1,106,1,161,1,131,1,130,1,
+ 116,4,160,5,116,6,124,2,124,1,106,7,161,3,1,0,
+ 100,1,83,0,41,3,122,19,69,120,101,99,117,116,101,32,
+ 116,104,101,32,109,111,100,117,108,101,46,78,122,52,99,97,
+ 110,110,111,116,32,108,111,97,100,32,109,111,100,117,108,101,
+ 32,123,33,114,125,32,119,104,101,110,32,103,101,116,95,99,
+ 111,100,101,40,41,32,114,101,116,117,114,110,115,32,78,111,
+ 110,101,41,8,218,8,103,101,116,95,99,111,100,101,114,149,
+ 0,0,0,114,141,0,0,0,114,88,0,0,0,114,158,0,
+ 0,0,218,25,95,99,97,108,108,95,119,105,116,104,95,102,
+ 114,97,109,101,115,95,114,101,109,111,118,101,100,218,4,101,
+ 120,101,99,114,155,0,0,0,41,3,114,142,0,0,0,218,
+ 6,109,111,100,117,108,101,114,188,0,0,0,114,10,0,0,
+ 0,114,10,0,0,0,114,11,0,0,0,218,11,101,120,101,
+ 99,95,109,111,100,117,108,101,76,3,0,0,115,12,0,0,
+ 0,0,2,12,1,8,1,6,1,4,255,6,2,122,25,95,
+ 76,111,97,100,101,114,66,97,115,105,99,115,46,101,120,101,
+ 99,95,109,111,100,117,108,101,99,2,0,0,0,0,0,0,
+ 0,0,0,0,0,2,0,0,0,4,0,0,0,67,0,0,
+ 0,115,12,0,0,0,116,0,160,1,124,0,124,1,161,2,
+ 83,0,41,1,122,26,84,104,105,115,32,109,111,100,117,108,
+ 101,32,105,115,32,100,101,112,114,101,99,97,116,101,100,46,
+ 41,2,114,158,0,0,0,218,17,95,108,111,97,100,95,109,
+ 111,100,117,108,101,95,115,104,105,109,169,2,114,142,0,0,
+ 0,114,163,0,0,0,114,10,0,0,0,114,10,0,0,0,
+ 114,11,0,0,0,218,11,108,111,97,100,95,109,111,100,117,
+ 108,101,84,3,0,0,115,2,0,0,0,0,2,122,25,95,
+ 76,111,97,100,101,114,66,97,115,105,99,115,46,108,111,97,
+ 100,95,109,111,100,117,108,101,78,41,8,114,149,0,0,0,
+ 114,148,0,0,0,114,150,0,0,0,114,151,0,0,0,114,
+ 206,0,0,0,114,235,0,0,0,114,240,0,0,0,114,243,
+ 0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,0,
+ 0,0,114,11,0,0,0,114,231,0,0,0,60,3,0,0,
+ 115,10,0,0,0,8,2,4,3,8,8,8,3,8,8,114,
+ 231,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,3,0,0,0,64,0,0,0,115,74,0,
+ 0,0,101,0,90,1,100,0,90,2,100,1,100,2,132,0,
+ 90,3,100,3,100,4,132,0,90,4,100,5,100,6,132,0,
+ 90,5,100,7,100,8,132,0,90,6,100,9,100,10,132,0,
+ 90,7,100,11,100,12,156,1,100,13,100,14,132,2,90,8,
+ 100,15,100,16,132,0,90,9,100,17,83,0,41,18,218,12,
+ 83,111,117,114,99,101,76,111,97,100,101,114,99,2,0,0,
+ 0,0,0,0,0,0,0,0,0,2,0,0,0,1,0,0,
+ 0,67,0,0,0,115,8,0,0,0,116,0,130,1,100,1,
+ 83,0,41,2,122,165,79,112,116,105,111,110,97,108,32,109,
+ 101,116,104,111,100,32,116,104,97,116,32,114,101,116,117,114,
+ 110,115,32,116,104,101,32,109,111,100,105,102,105,99,97,116,
+ 105,111,110,32,116,105,109,101,32,40,97,110,32,105,110,116,
+ 41,32,102,111,114,32,116,104,101,10,32,32,32,32,32,32,
+ 32,32,115,112,101,99,105,102,105,101,100,32,112,97,116,104,
+ 32,40,97,32,115,116,114,41,46,10,10,32,32,32,32,32,
+ 32,32,32,82,97,105,115,101,115,32,79,83,69,114,114,111,
+ 114,32,119,104,101,110,32,116,104,101,32,112,97,116,104,32,
+ 99,97,110,110,111,116,32,98,101,32,104,97,110,100,108,101,
+ 100,46,10,32,32,32,32,32,32,32,32,78,41,1,114,76,
+ 0,0,0,169,2,114,142,0,0,0,114,65,0,0,0,114,
+ 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,10,
+ 112,97,116,104,95,109,116,105,109,101,91,3,0,0,115,2,
+ 0,0,0,0,6,122,23,83,111,117,114,99,101,76,111,97,
+ 100,101,114,46,112,97,116,104,95,109,116,105,109,101,99,2,
+ 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,4,
+ 0,0,0,67,0,0,0,115,14,0,0,0,100,1,124,0,
+ 160,0,124,1,161,1,105,1,83,0,41,2,97,158,1,0,
+ 0,79,112,116,105,111,110,97,108,32,109,101,116,104,111,100,
+ 32,114,101,116,117,114,110,105,110,103,32,97,32,109,101,116,
+ 97,100,97,116,97,32,100,105,99,116,32,102,111,114,32,116,
+ 104,101,32,115,112,101,99,105,102,105,101,100,10,32,32,32,
+ 32,32,32,32,32,112,97,116,104,32,40,97,32,115,116,114,
+ 41,46,10,10,32,32,32,32,32,32,32,32,80,111,115,115,
+ 105,98,108,101,32,107,101,121,115,58,10,32,32,32,32,32,
+ 32,32,32,45,32,39,109,116,105,109,101,39,32,40,109,97,
+ 110,100,97,116,111,114,121,41,32,105,115,32,116,104,101,32,
+ 110,117,109,101,114,105,99,32,116,105,109,101,115,116,97,109,
+ 112,32,111,102,32,108,97,115,116,32,115,111,117,114,99,101,
+ 10,32,32,32,32,32,32,32,32,32,32,99,111,100,101,32,
+ 109,111,100,105,102,105,99,97,116,105,111,110,59,10,32,32,
+ 32,32,32,32,32,32,45,32,39,115,105,122,101,39,32,40,
+ 111,112,116,105,111,110,97,108,41,32,105,115,32,116,104,101,
+ 32,115,105,122,101,32,105,110,32,98,121,116,101,115,32,111,
+ 102,32,116,104,101,32,115,111,117,114,99,101,32,99,111,100,
+ 101,46,10,10,32,32,32,32,32,32,32,32,73,109,112,108,
+ 101,109,101,110,116,105,110,103,32,116,104,105,115,32,109,101,
+ 116,104,111,100,32,97,108,108,111,119,115,32,116,104,101,32,
+ 108,111,97,100,101,114,32,116,111,32,114,101,97,100,32,98,
+ 121,116,101,99,111,100,101,32,102,105,108,101,115,46,10,32,
+ 32,32,32,32,32,32,32,82,97,105,115,101,115,32,79,83,
+ 69,114,114,111,114,32,119,104,101,110,32,116,104,101,32,112,
+ 97,116,104,32,99,97,110,110,111,116,32,98,101,32,104,97,
+ 110,100,108,101,100,46,10,32,32,32,32,32,32,32,32,114,
+ 193,0,0,0,41,1,114,246,0,0,0,114,245,0,0,0,
+ 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,
+ 10,112,97,116,104,95,115,116,97,116,115,99,3,0,0,115,
+ 2,0,0,0,0,12,122,23,83,111,117,114,99,101,76,111,
+ 97,100,101,114,46,112,97,116,104,95,115,116,97,116,115,99,
+ 4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,
+ 4,0,0,0,67,0,0,0,115,12,0,0,0,124,0,160,
+ 0,124,2,124,3,161,2,83,0,41,1,122,228,79,112,116,
+ 105,111,110,97,108,32,109,101,116,104,111,100,32,119,104,105,
+ 99,104,32,119,114,105,116,101,115,32,100,97,116,97,32,40,
+ 98,121,116,101,115,41,32,116,111,32,97,32,102,105,108,101,
+ 32,112,97,116,104,32,40,97,32,115,116,114,41,46,10,10,
+ 32,32,32,32,32,32,32,32,73,109,112,108,101,109,101,110,
+ 116,105,110,103,32,116,104,105,115,32,109,101,116,104,111,100,
+ 32,97,108,108,111,119,115,32,102,111,114,32,116,104,101,32,
+ 119,114,105,116,105,110,103,32,111,102,32,98,121,116,101,99,
+ 111,100,101,32,102,105,108,101,115,46,10,10,32,32,32,32,
+ 32,32,32,32,84,104,101,32,115,111,117,114,99,101,32,112,
+ 97,116,104,32,105,115,32,110,101,101,100,101,100,32,105,110,
+ 32,111,114,100,101,114,32,116,111,32,99,111,114,114,101,99,
+ 116,108,121,32,116,114,97,110,115,102,101,114,32,112,101,114,
+ 109,105,115,115,105,111,110,115,10,32,32,32,32,32,32,32,
+ 32,41,1,218,8,115,101,116,95,100,97,116,97,41,4,114,
+ 142,0,0,0,114,133,0,0,0,90,10,99,97,99,104,101,
+ 95,112,97,116,104,114,43,0,0,0,114,10,0,0,0,114,
+ 10,0,0,0,114,11,0,0,0,218,15,95,99,97,99,104,
+ 101,95,98,121,116,101,99,111,100,101,113,3,0,0,115,2,
+ 0,0,0,0,8,122,28,83,111,117,114,99,101,76,111,97,
+ 100,101,114,46,95,99,97,99,104,101,95,98,121,116,101,99,
+ 111,100,101,99,3,0,0,0,0,0,0,0,0,0,0,0,
+ 3,0,0,0,1,0,0,0,67,0,0,0,115,4,0,0,
+ 0,100,1,83,0,41,2,122,150,79,112,116,105,111,110,97,
+ 108,32,109,101,116,104,111,100,32,119,104,105,99,104,32,119,
+ 114,105,116,101,115,32,100,97,116,97,32,40,98,121,116,101,
+ 115,41,32,116,111,32,97,32,102,105,108,101,32,112,97,116,
+ 104,32,40,97,32,115,116,114,41,46,10,10,32,32,32,32,
+ 32,32,32,32,73,109,112,108,101,109,101,110,116,105,110,103,
+ 32,116,104,105,115,32,109,101,116,104,111,100,32,97,108,108,
+ 111,119,115,32,102,111,114,32,116,104,101,32,119,114,105,116,
+ 105,110,103,32,111,102,32,98,121,116,101,99,111,100,101,32,
+ 102,105,108,101,115,46,10,32,32,32,32,32,32,32,32,78,
+ 114,10,0,0,0,41,3,114,142,0,0,0,114,65,0,0,
+ 0,114,43,0,0,0,114,10,0,0,0,114,10,0,0,0,
+ 114,11,0,0,0,114,248,0,0,0,123,3,0,0,115,2,
+ 0,0,0,0,1,122,21,83,111,117,114,99,101,76,111,97,
+ 100,101,114,46,115,101,116,95,100,97,116,97,99,2,0,0,
+ 0,0,0,0,0,0,0,0,0,5,0,0,0,10,0,0,
+ 0,67,0,0,0,115,84,0,0,0,124,0,160,0,124,1,
+ 161,1,125,2,122,14,124,0,160,1,124,2,161,1,125,3,
+ 87,0,110,50,4,0,116,2,121,74,1,0,125,4,1,0,
+ 122,26,116,3,100,1,124,1,100,2,141,2,124,4,130,2,
+ 87,0,89,0,100,3,125,4,126,4,110,10,100,3,125,4,
+ 126,4,48,0,48,0,116,4,124,3,131,1,83,0,41,4,
+ 122,52,67,111,110,99,114,101,116,101,32,105,109,112,108,101,
+ 109,101,110,116,97,116,105,111,110,32,111,102,32,73,110,115,
+ 112,101,99,116,76,111,97,100,101,114,46,103,101,116,95,115,
+ 111,117,114,99,101,46,122,39,115,111,117,114,99,101,32,110,
+ 111,116,32,97,118,97,105,108,97,98,108,101,32,116,104,114,
+ 111,117,103,104,32,103,101,116,95,100,97,116,97,40,41,114,
+ 139,0,0,0,78,41,5,114,203,0,0,0,218,8,103,101,
+ 116,95,100,97,116,97,114,76,0,0,0,114,141,0,0,0,
+ 114,200,0,0,0,41,5,114,142,0,0,0,114,163,0,0,
+ 0,114,65,0,0,0,114,198,0,0,0,218,3,101,120,99,
+ 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,
+ 10,103,101,116,95,115,111,117,114,99,101,130,3,0,0,115,
+ 20,0,0,0,0,2,10,1,2,1,14,1,14,1,4,1,
+ 2,255,4,1,2,255,24,2,122,23,83,111,117,114,99,101,
+ 76,111,97,100,101,114,46,103,101,116,95,115,111,117,114,99,
+ 101,114,129,0,0,0,41,1,218,9,95,111,112,116,105,109,
+ 105,122,101,99,3,0,0,0,0,0,0,0,1,0,0,0,
+ 4,0,0,0,8,0,0,0,67,0,0,0,115,22,0,0,
+ 0,116,0,106,1,116,2,124,1,124,2,100,1,100,2,124,
+ 3,100,3,141,6,83,0,41,4,122,130,82,101,116,117,114,
+ 110,32,116,104,101,32,99,111,100,101,32,111,98,106,101,99,
+ 116,32,99,111,109,112,105,108,101,100,32,102,114,111,109,32,
+ 115,111,117,114,99,101,46,10,10,32,32,32,32,32,32,32,
+ 32,84,104,101,32,39,100,97,116,97,39,32,97,114,103,117,
+ 109,101,110,116,32,99,97,110,32,98,101,32,97,110,121,32,
+ 111,98,106,101,99,116,32,116,121,112,101,32,116,104,97,116,
+ 32,99,111,109,112,105,108,101,40,41,32,115,117,112,112,111,
+ 114,116,115,46,10,32,32,32,32,32,32,32,32,114,238,0,
+ 0,0,84,41,2,218,12,100,111,110,116,95,105,110,104,101,
+ 114,105,116,114,107,0,0,0,41,3,114,158,0,0,0,114,
+ 237,0,0,0,218,7,99,111,109,112,105,108,101,41,4,114,
+ 142,0,0,0,114,43,0,0,0,114,65,0,0,0,114,253,
+ 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,
+ 0,0,218,14,115,111,117,114,99,101,95,116,111,95,99,111,
+ 100,101,140,3,0,0,115,6,0,0,0,0,5,12,1,4,
+ 255,122,27,83,111,117,114,99,101,76,111,97,100,101,114,46,
+ 115,111,117,114,99,101,95,116,111,95,99,111,100,101,99,2,
+ 0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,9,
+ 0,0,0,67,0,0,0,115,24,2,0,0,124,0,160,0,
+ 124,1,161,1,125,2,100,1,125,3,100,1,125,4,100,1,
+ 125,5,100,2,125,6,100,3,125,7,122,12,116,1,124,2,
+ 131,1,125,8,87,0,110,24,4,0,116,2,121,66,1,0,
+ 1,0,1,0,100,1,125,8,89,0,144,1,110,42,48,0,
+ 122,14,124,0,160,3,124,2,161,1,125,9,87,0,110,20,
+ 4,0,116,4,121,102,1,0,1,0,1,0,89,0,144,1,
+ 110,6,48,0,116,5,124,9,100,4,25,0,131,1,125,3,
+ 122,14,124,0,160,6,124,8,161,1,125,10,87,0,110,18,
+ 4,0,116,4,121,148,1,0,1,0,1,0,89,0,110,216,
+ 48,0,124,1,124,8,100,5,156,2,125,11,122,148,116,7,
+ 124,10,124,1,124,11,131,3,125,12,116,8,124,10,131,1,
+ 100,6,100,1,133,2,25,0,125,13,124,12,100,7,64,0,
+ 100,8,107,3,125,6,124,6,144,1,114,30,124,12,100,9,
+ 64,0,100,8,107,3,125,7,116,9,106,10,100,10,107,3,
+ 144,1,114,50,124,7,115,248,116,9,106,10,100,11,107,2,
+ 144,1,114,50,124,0,160,6,124,2,161,1,125,4,116,9,
+ 160,11,116,12,124,4,161,2,125,5,116,13,124,10,124,5,
+ 124,1,124,11,131,4,1,0,110,20,116,14,124,10,124,3,
+ 124,9,100,12,25,0,124,1,124,11,131,5,1,0,87,0,
+ 110,24,4,0,116,15,116,16,102,2,144,1,121,76,1,0,
+ 1,0,1,0,89,0,110,32,48,0,116,17,160,18,100,13,
+ 124,8,124,2,161,3,1,0,116,19,124,13,124,1,124,8,
+ 124,2,100,14,141,4,83,0,124,4,100,1,117,0,144,1,
+ 114,128,124,0,160,6,124,2,161,1,125,4,124,0,160,20,
+ 124,4,124,2,161,2,125,14,116,17,160,18,100,15,124,2,
+ 161,2,1,0,116,21,106,22,144,2,115,20,124,8,100,1,
+ 117,1,144,2,114,20,124,3,100,1,117,1,144,2,114,20,
+ 124,6,144,1,114,220,124,5,100,1,117,0,144,1,114,206,
+ 116,9,160,11,124,4,161,1,125,5,116,23,124,14,124,5,
+ 124,7,131,3,125,10,110,16,116,24,124,14,124,3,116,25,
+ 124,4,131,1,131,3,125,10,122,18,124,0,160,26,124,2,
+ 124,8,124,10,161,3,1,0,87,0,110,20,4,0,116,2,
+ 144,2,121,18,1,0,1,0,1,0,89,0,110,2,48,0,
+ 124,14,83,0,41,16,122,190,67,111,110,99,114,101,116,101,
+ 32,105,109,112,108,101,109,101,110,116,97,116,105,111,110,32,
+ 111,102,32,73,110,115,112,101,99,116,76,111,97,100,101,114,
+ 46,103,101,116,95,99,111,100,101,46,10,10,32,32,32,32,
+ 32,32,32,32,82,101,97,100,105,110,103,32,111,102,32,98,
+ 121,116,101,99,111,100,101,32,114,101,113,117,105,114,101,115,
+ 32,112,97,116,104,95,115,116,97,116,115,32,116,111,32,98,
+ 101,32,105,109,112,108,101,109,101,110,116,101,100,46,32,84,
+ 111,32,119,114,105,116,101,10,32,32,32,32,32,32,32,32,
+ 98,121,116,101,99,111,100,101,44,32,115,101,116,95,100,97,
+ 116,97,32,109,117,115,116,32,97,108,115,111,32,98,101,32,
+ 105,109,112,108,101,109,101,110,116,101,100,46,10,10,32,32,
+ 32,32,32,32,32,32,78,70,84,114,193,0,0,0,114,183,
+ 0,0,0,114,169,0,0,0,114,4,0,0,0,114,0,0,
+ 0,0,114,45,0,0,0,90,5,110,101,118,101,114,90,6,
+ 97,108,119,97,121,115,218,4,115,105,122,101,122,13,123,125,
+ 32,109,97,116,99,104,101,115,32,123,125,41,3,114,140,0,
+ 0,0,114,131,0,0,0,114,133,0,0,0,122,19,99,111,
+ 100,101,32,111,98,106,101,99,116,32,102,114,111,109,32,123,
+ 125,41,27,114,203,0,0,0,114,120,0,0,0,114,106,0,
+ 0,0,114,247,0,0,0,114,76,0,0,0,114,36,0,0,
+ 0,114,250,0,0,0,114,176,0,0,0,218,10,109,101,109,
+ 111,114,121,118,105,101,119,114,187,0,0,0,90,21,99,104,
+ 101,99,107,95,104,97,115,104,95,98,97,115,101,100,95,112,
+ 121,99,115,114,181,0,0,0,218,17,95,82,65,87,95,77,
+ 65,71,73,67,95,78,85,77,66,69,82,114,182,0,0,0,
+ 114,180,0,0,0,114,141,0,0,0,114,174,0,0,0,114,
+ 158,0,0,0,114,173,0,0,0,114,189,0,0,0,114,0,
+ 1,0,0,114,21,0,0,0,218,19,100,111,110,116,95,119,
+ 114,105,116,101,95,98,121,116,101,99,111,100,101,114,195,0,
+ 0,0,114,194,0,0,0,114,6,0,0,0,114,249,0,0,
+ 0,41,15,114,142,0,0,0,114,163,0,0,0,114,133,0,
+ 0,0,114,178,0,0,0,114,198,0,0,0,114,181,0,0,
+ 0,90,10,104,97,115,104,95,98,97,115,101,100,90,12,99,
+ 104,101,99,107,95,115,111,117,114,99,101,114,131,0,0,0,
+ 218,2,115,116,114,43,0,0,0,114,175,0,0,0,114,22,
+ 0,0,0,90,10,98,121,116,101,115,95,100,97,116,97,90,
+ 11,99,111,100,101,95,111,98,106,101,99,116,114,10,0,0,
+ 0,114,10,0,0,0,114,11,0,0,0,114,236,0,0,0,
+ 148,3,0,0,115,152,0,0,0,0,7,10,1,4,1,4,
+ 1,4,1,4,1,4,1,2,1,12,1,12,1,12,2,2,
+ 1,14,1,12,1,8,2,12,1,2,1,14,1,12,1,6,
+ 3,2,1,2,254,6,4,2,1,12,1,16,1,12,1,6,
+ 1,12,1,12,1,2,255,2,2,8,254,4,3,10,1,4,
+ 1,2,1,2,254,4,4,8,1,2,255,6,3,2,1,2,
+ 1,2,1,6,1,2,1,2,251,8,7,18,1,6,2,8,
+ 1,2,255,4,2,6,1,2,1,2,254,6,3,10,1,10,
+ 1,12,1,12,1,18,1,6,255,4,2,6,1,10,1,10,
+ 1,14,2,6,1,6,255,4,2,2,1,18,1,14,1,6,
+ 1,122,21,83,111,117,114,99,101,76,111,97,100,101,114,46,
+ 103,101,116,95,99,111,100,101,78,41,10,114,149,0,0,0,
+ 114,148,0,0,0,114,150,0,0,0,114,246,0,0,0,114,
+ 247,0,0,0,114,249,0,0,0,114,248,0,0,0,114,252,
+ 0,0,0,114,0,1,0,0,114,236,0,0,0,114,10,0,
+ 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+ 0,114,244,0,0,0,89,3,0,0,115,14,0,0,0,8,
+ 2,8,8,8,14,8,10,8,7,8,10,14,8,114,244,0,
+ 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,4,0,0,0,0,0,0,0,115,124,0,0,0,
+ 101,0,90,1,100,0,90,2,100,1,90,3,100,2,100,3,
+ 132,0,90,4,100,4,100,5,132,0,90,5,100,6,100,7,
+ 132,0,90,6,101,7,135,0,102,1,100,8,100,9,132,8,
+ 131,1,90,8,101,7,100,10,100,11,132,0,131,1,90,9,
+ 100,12,100,13,132,0,90,10,101,7,100,14,100,15,132,0,
+ 131,1,90,11,100,16,100,17,132,0,90,12,100,18,100,19,
+ 132,0,90,13,100,20,100,21,132,0,90,14,100,22,100,23,
+ 132,0,90,15,135,0,4,0,90,16,83,0,41,24,218,10,
+ 70,105,108,101,76,111,97,100,101,114,122,103,66,97,115,101,
+ 32,102,105,108,101,32,108,111,97,100,101,114,32,99,108,97,
+ 115,115,32,119,104,105,99,104,32,105,109,112,108,101,109,101,
+ 110,116,115,32,116,104,101,32,108,111,97,100,101,114,32,112,
+ 114,111,116,111,99,111,108,32,109,101,116,104,111,100,115,32,
+ 116,104,97,116,10,32,32,32,32,114,101,113,117,105,114,101,
+ 32,102,105,108,101,32,115,121,115,116,101,109,32,117,115,97,
+ 103,101,46,99,3,0,0,0,0,0,0,0,0,0,0,0,
+ 3,0,0,0,2,0,0,0,67,0,0,0,115,16,0,0,
+ 0,124,1,124,0,95,0,124,2,124,0,95,1,100,1,83,
+ 0,41,2,122,75,67,97,99,104,101,32,116,104,101,32,109,
+ 111,100,117,108,101,32,110,97,109,101,32,97,110,100,32,116,
+ 104,101,32,112,97,116,104,32,116,111,32,116,104,101,32,102,
+ 105,108,101,32,102,111,117,110,100,32,98,121,32,116,104,101,
+ 10,32,32,32,32,32,32,32,32,102,105,110,100,101,114,46,
+ 78,114,183,0,0,0,41,3,114,142,0,0,0,114,163,0,
+ 0,0,114,65,0,0,0,114,10,0,0,0,114,10,0,0,
+ 0,114,11,0,0,0,114,232,0,0,0,238,3,0,0,115,
+ 4,0,0,0,0,3,6,1,122,19,70,105,108,101,76,111,
+ 97,100,101,114,46,95,95,105,110,105,116,95,95,99,2,0,
+ 0,0,0,0,0,0,0,0,0,0,2,0,0,0,2,0,
+ 0,0,67,0,0,0,115,24,0,0,0,124,0,106,0,124,
+ 1,106,0,107,2,111,22,124,0,106,1,124,1,106,1,107,
+ 2,83,0,114,69,0,0,0,169,2,218,9,95,95,99,108,
+ 97,115,115,95,95,114,155,0,0,0,169,2,114,142,0,0,
+ 0,90,5,111,116,104,101,114,114,10,0,0,0,114,10,0,
+ 0,0,114,11,0,0,0,218,6,95,95,101,113,95,95,244,
+ 3,0,0,115,6,0,0,0,0,1,12,1,10,255,122,17,
+ 70,105,108,101,76,111,97,100,101,114,46,95,95,101,113,95,
+ 95,99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,
+ 0,0,3,0,0,0,67,0,0,0,115,20,0,0,0,116,
+ 0,124,0,106,1,131,1,116,0,124,0,106,2,131,1,65,
+ 0,83,0,114,69,0,0,0,169,3,218,4,104,97,115,104,
+ 114,140,0,0,0,114,65,0,0,0,169,1,114,142,0,0,
+ 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
+ 218,8,95,95,104,97,115,104,95,95,248,3,0,0,115,2,
+ 0,0,0,0,1,122,19,70,105,108,101,76,111,97,100,101,
+ 114,46,95,95,104,97,115,104,95,95,99,2,0,0,0,0,
+ 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,3,
+ 0,0,0,115,16,0,0,0,116,0,116,1,124,0,131,2,
+ 160,2,124,1,161,1,83,0,41,1,122,100,76,111,97,100,
+ 32,97,32,109,111,100,117,108,101,32,102,114,111,109,32,97,
+ 32,102,105,108,101,46,10,10,32,32,32,32,32,32,32,32,
+ 84,104,105,115,32,109,101,116,104,111,100,32,105,115,32,100,
+ 101,112,114,101,99,97,116,101,100,46,32,32,85,115,101,32,
+ 101,120,101,99,95,109,111,100,117,108,101,40,41,32,105,110,
+ 115,116,101,97,100,46,10,10,32,32,32,32,32,32,32,32,
+ 41,3,218,5,115,117,112,101,114,114,6,1,0,0,114,243,
+ 0,0,0,114,242,0,0,0,169,1,114,8,1,0,0,114,
+ 10,0,0,0,114,11,0,0,0,114,243,0,0,0,251,3,
+ 0,0,115,2,0,0,0,0,10,122,22,70,105,108,101,76,
+ 111,97,100,101,114,46,108,111,97,100,95,109,111,100,117,108,
+ 101,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,
+ 0,0,1,0,0,0,67,0,0,0,115,6,0,0,0,124,
+ 0,106,0,83,0,169,1,122,58,82,101,116,117,114,110,32,
+ 116,104,101,32,112,97,116,104,32,116,111,32,116,104,101,32,
+ 115,111,117,114,99,101,32,102,105,108,101,32,97,115,32,102,
+ 111,117,110,100,32,98,121,32,116,104,101,32,102,105,110,100,
+ 101,114,46,114,71,0,0,0,114,242,0,0,0,114,10,0,
+ 0,0,114,10,0,0,0,114,11,0,0,0,114,203,0,0,
+ 0,7,4,0,0,115,2,0,0,0,0,3,122,23,70,105,
+ 108,101,76,111,97,100,101,114,46,103,101,116,95,102,105,108,
+ 101,110,97,109,101,99,2,0,0,0,0,0,0,0,0,0,
+ 0,0,3,0,0,0,8,0,0,0,67,0,0,0,115,126,
+ 0,0,0,116,0,124,0,116,1,116,2,102,2,131,2,114,
+ 70,116,3,160,4,116,5,124,1,131,1,161,1,143,24,125,
+ 2,124,2,160,6,161,0,87,0,2,0,100,1,4,0,4,
+ 0,131,3,1,0,83,0,49,0,115,58,48,0,1,0,1,
+ 0,1,0,89,0,1,0,110,52,116,3,160,7,124,1,100,
+ 2,161,2,143,24,125,2,124,2,160,6,161,0,87,0,2,
+ 0,100,1,4,0,4,0,131,3,1,0,83,0,49,0,115,
+ 112,48,0,1,0,1,0,1,0,89,0,1,0,100,1,83,
+ 0,41,3,122,39,82,101,116,117,114,110,32,116,104,101,32,
+ 100,97,116,97,32,102,114,111,109,32,112,97,116,104,32,97,
+ 115,32,114,97,119,32,98,121,116,101,115,46,78,218,1,114,
+ 41,8,114,185,0,0,0,114,244,0,0,0,218,19,69,120,
+ 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,
+ 114,114,90,0,0,0,90,9,111,112,101,110,95,99,111,100,
+ 101,114,108,0,0,0,90,4,114,101,97,100,114,91,0,0,
+ 0,41,3,114,142,0,0,0,114,65,0,0,0,114,93,0,
+ 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+ 0,114,250,0,0,0,12,4,0,0,115,10,0,0,0,0,
+ 2,14,1,16,1,40,2,14,1,122,19,70,105,108,101,76,
+ 111,97,100,101,114,46,103,101,116,95,100,97,116,97,99,2,
+ 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,3,
+ 0,0,0,67,0,0,0,115,18,0,0,0,124,0,160,0,
+ 124,1,161,1,114,14,124,0,83,0,100,0,83,0,114,69,
+ 0,0,0,41,1,114,206,0,0,0,169,2,114,142,0,0,
+ 0,114,239,0,0,0,114,10,0,0,0,114,10,0,0,0,
+ 114,11,0,0,0,218,19,103,101,116,95,114,101,115,111,117,
+ 114,99,101,95,114,101,97,100,101,114,23,4,0,0,115,6,
+ 0,0,0,0,2,10,1,4,1,122,30,70,105,108,101,76,
+ 111,97,100,101,114,46,103,101,116,95,114,101,115,111,117,114,
+ 99,101,95,114,101,97,100,101,114,99,2,0,0,0,0,0,
+ 0,0,0,0,0,0,3,0,0,0,4,0,0,0,67,0,
+ 0,0,115,32,0,0,0,116,0,116,1,124,0,106,2,131,
+ 1,100,1,25,0,124,1,131,2,125,2,116,3,160,4,124,
+ 2,100,2,161,2,83,0,41,3,78,114,0,0,0,0,114,
+ 18,1,0,0,41,5,114,67,0,0,0,114,74,0,0,0,
+ 114,65,0,0,0,114,90,0,0,0,114,91,0,0,0,169,
+ 3,114,142,0,0,0,90,8,114,101,115,111,117,114,99,101,
+ 114,65,0,0,0,114,10,0,0,0,114,10,0,0,0,114,
+ 11,0,0,0,218,13,111,112,101,110,95,114,101,115,111,117,
+ 114,99,101,29,4,0,0,115,4,0,0,0,0,1,20,1,
+ 122,24,70,105,108,101,76,111,97,100,101,114,46,111,112,101,
+ 110,95,114,101,115,111,117,114,99,101,99,2,0,0,0,0,
+ 0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,67,
+ 0,0,0,115,38,0,0,0,124,0,160,0,124,1,161,1,
+ 115,14,116,1,130,1,116,2,116,3,124,0,106,4,131,1,
+ 100,1,25,0,124,1,131,2,125,2,124,2,83,0,169,2,
+ 78,114,0,0,0,0,41,5,218,11,105,115,95,114,101,115,
+ 111,117,114,99,101,218,17,70,105,108,101,78,111,116,70,111,
+ 117,110,100,69,114,114,111,114,114,67,0,0,0,114,74,0,
+ 0,0,114,65,0,0,0,114,22,1,0,0,114,10,0,0,
+ 0,114,10,0,0,0,114,11,0,0,0,218,13,114,101,115,
+ 111,117,114,99,101,95,112,97,116,104,33,4,0,0,115,8,
+ 0,0,0,0,1,10,1,4,1,20,1,122,24,70,105,108,
+ 101,76,111,97,100,101,114,46,114,101,115,111,117,114,99,101,
+ 95,112,97,116,104,99,2,0,0,0,0,0,0,0,0,0,
+ 0,0,3,0,0,0,3,0,0,0,67,0,0,0,115,40,
+ 0,0,0,116,0,124,1,118,0,114,12,100,1,83,0,116,
+ 1,116,2,124,0,106,3,131,1,100,2,25,0,124,1,131,
+ 2,125,2,116,4,124,2,131,1,83,0,41,3,78,70,114,
+ 0,0,0,0,41,5,114,59,0,0,0,114,67,0,0,0,
+ 114,74,0,0,0,114,65,0,0,0,114,80,0,0,0,169,
+ 3,114,142,0,0,0,114,140,0,0,0,114,65,0,0,0,
+ 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,
+ 25,1,0,0,39,4,0,0,115,8,0,0,0,0,1,8,
+ 1,4,1,20,1,122,22,70,105,108,101,76,111,97,100,101,
+ 114,46,105,115,95,114,101,115,111,117,114,99,101,99,1,0,
+ 0,0,0,0,0,0,0,0,0,0,1,0,0,0,5,0,
+ 0,0,67,0,0,0,115,24,0,0,0,116,0,116,1,160,
+ 2,116,3,124,0,106,4,131,1,100,1,25,0,161,1,131,
+ 1,83,0,114,24,1,0,0,41,5,218,4,105,116,101,114,
+ 114,24,0,0,0,218,7,108,105,115,116,100,105,114,114,74,
+ 0,0,0,114,65,0,0,0,114,13,1,0,0,114,10,0,
+ 0,0,114,10,0,0,0,114,11,0,0,0,218,8,99,111,
+ 110,116,101,110,116,115,45,4,0,0,115,2,0,0,0,0,
+ 1,122,19,70,105,108,101,76,111,97,100,101,114,46,99,111,
+ 110,116,101,110,116,115,41,17,114,149,0,0,0,114,148,0,
+ 0,0,114,150,0,0,0,114,151,0,0,0,114,232,0,0,
+ 0,114,10,1,0,0,114,14,1,0,0,114,160,0,0,0,
+ 114,243,0,0,0,114,203,0,0,0,114,250,0,0,0,114,
+ 21,1,0,0,114,23,1,0,0,114,27,1,0,0,114,25,
+ 1,0,0,114,31,1,0,0,90,13,95,95,99,108,97,115,
+ 115,99,101,108,108,95,95,114,10,0,0,0,114,10,0,0,
+ 0,114,16,1,0,0,114,11,0,0,0,114,6,1,0,0,
+ 233,3,0,0,115,30,0,0,0,8,2,4,3,8,6,8,
+ 4,8,3,2,1,14,11,2,1,10,4,8,11,2,1,10,
+ 5,8,4,8,6,8,6,114,6,1,0,0,99,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,
+ 0,64,0,0,0,115,46,0,0,0,101,0,90,1,100,0,
+ 90,2,100,1,90,3,100,2,100,3,132,0,90,4,100,4,
+ 100,5,132,0,90,5,100,6,100,7,156,1,100,8,100,9,
+ 132,2,90,6,100,10,83,0,41,11,218,16,83,111,117,114,
+ 99,101,70,105,108,101,76,111,97,100,101,114,122,62,67,111,
+ 110,99,114,101,116,101,32,105,109,112,108,101,109,101,110,116,
+ 97,116,105,111,110,32,111,102,32,83,111,117,114,99,101,76,
+ 111,97,100,101,114,32,117,115,105,110,103,32,116,104,101,32,
+ 102,105,108,101,32,115,121,115,116,101,109,46,99,2,0,0,
+ 0,0,0,0,0,0,0,0,0,3,0,0,0,3,0,0,
+ 0,67,0,0,0,115,22,0,0,0,116,0,124,1,131,1,
+ 125,2,124,2,106,1,124,2,106,2,100,1,156,2,83,0,
+ 41,2,122,33,82,101,116,117,114,110,32,116,104,101,32,109,
+ 101,116,97,100,97,116,97,32,102,111,114,32,116,104,101,32,
+ 112,97,116,104,46,41,2,114,193,0,0,0,114,1,1,0,
+ 0,41,3,114,75,0,0,0,218,8,115,116,95,109,116,105,
+ 109,101,90,7,115,116,95,115,105,122,101,41,3,114,142,0,
+ 0,0,114,65,0,0,0,114,5,1,0,0,114,10,0,0,
+ 0,114,10,0,0,0,114,11,0,0,0,114,247,0,0,0,
+ 53,4,0,0,115,4,0,0,0,0,2,8,1,122,27,83,
+ 111,117,114,99,101,70,105,108,101,76,111,97,100,101,114,46,
+ 112,97,116,104,95,115,116,97,116,115,99,4,0,0,0,0,
+ 0,0,0,0,0,0,0,5,0,0,0,5,0,0,0,67,
+ 0,0,0,115,24,0,0,0,116,0,124,1,131,1,125,4,
+ 124,0,106,1,124,2,124,3,124,4,100,1,141,3,83,0,
+ 41,2,78,169,1,218,5,95,109,111,100,101,41,2,114,138,
+ 0,0,0,114,248,0,0,0,41,5,114,142,0,0,0,114,
+ 133,0,0,0,114,131,0,0,0,114,43,0,0,0,114,78,
+ 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,
+ 0,0,114,249,0,0,0,58,4,0,0,115,4,0,0,0,
+ 0,2,8,1,122,32,83,111,117,114,99,101,70,105,108,101,
+ 76,111,97,100,101,114,46,95,99,97,99,104,101,95,98,121,
+ 116,101,99,111,100,101,114,86,0,0,0,114,34,1,0,0,
+ 99,3,0,0,0,0,0,0,0,1,0,0,0,9,0,0,
+ 0,11,0,0,0,67,0,0,0,115,252,0,0,0,116,0,
+ 124,1,131,1,92,2,125,4,125,5,103,0,125,6,124,4,
+ 114,52,116,1,124,4,131,1,115,52,116,0,124,4,131,1,
+ 92,2,125,4,125,7,124,6,160,2,124,7,161,1,1,0,
+ 113,16,116,3,124,6,131,1,68,0,93,104,125,7,116,4,
+ 124,4,124,7,131,2,125,4,122,14,116,5,160,6,124,4,
+ 161,1,1,0,87,0,113,60,4,0,116,7,121,110,1,0,
+ 1,0,1,0,89,0,113,60,89,0,113,60,4,0,116,8,
+ 121,162,1,0,125,8,1,0,122,30,116,9,160,10,100,1,
+ 124,4,124,8,161,3,1,0,87,0,89,0,100,2,125,8,
+ 126,8,1,0,100,2,83,0,100,2,125,8,126,8,48,0,
+ 48,0,113,60,122,28,116,11,124,1,124,2,124,3,131,3,
+ 1,0,116,9,160,10,100,3,124,1,161,2,1,0,87,0,
+ 110,52,4,0,116,8,144,0,121,246,1,0,125,8,1,0,
+ 122,26,116,9,160,10,100,1,124,1,124,8,161,3,1,0,
+ 87,0,89,0,100,2,125,8,126,8,110,10,100,2,125,8,
+ 126,8,48,0,48,0,100,2,83,0,41,4,122,27,87,114,
+ 105,116,101,32,98,121,116,101,115,32,100,97,116,97,32,116,
+ 111,32,97,32,102,105,108,101,46,122,27,99,111,117,108,100,
+ 32,110,111,116,32,99,114,101,97,116,101,32,123,33,114,125,
+ 58,32,123,33,114,125,78,122,12,99,114,101,97,116,101,100,
+ 32,123,33,114,125,41,12,114,74,0,0,0,114,82,0,0,
+ 0,114,61,0,0,0,218,8,114,101,118,101,114,115,101,100,
+ 114,67,0,0,0,114,24,0,0,0,90,5,109,107,100,105,
+ 114,218,15,70,105,108,101,69,120,105,115,116,115,69,114,114,
+ 111,114,114,76,0,0,0,114,158,0,0,0,114,173,0,0,
+ 0,114,94,0,0,0,41,9,114,142,0,0,0,114,65,0,
+ 0,0,114,43,0,0,0,114,35,1,0,0,218,6,112,97,
+ 114,101,110,116,114,119,0,0,0,114,63,0,0,0,114,68,
+ 0,0,0,114,251,0,0,0,114,10,0,0,0,114,10,0,
+ 0,0,114,11,0,0,0,114,248,0,0,0,63,4,0,0,
+ 115,46,0,0,0,0,2,12,1,4,2,12,1,12,1,12,
+ 2,12,1,10,1,2,1,14,1,12,2,8,1,14,3,6,
+ 1,4,255,4,2,28,1,2,1,12,1,16,1,16,2,8,
+ 1,2,255,122,25,83,111,117,114,99,101,70,105,108,101,76,
+ 111,97,100,101,114,46,115,101,116,95,100,97,116,97,78,41,
+ 7,114,149,0,0,0,114,148,0,0,0,114,150,0,0,0,
+ 114,151,0,0,0,114,247,0,0,0,114,249,0,0,0,114,
+ 248,0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,
+ 0,0,0,114,11,0,0,0,114,32,1,0,0,49,4,0,
+ 0,115,8,0,0,0,8,2,4,2,8,5,8,5,114,32,
+ 1,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,2,0,0,0,64,0,0,0,115,32,0,0,
+ 0,101,0,90,1,100,0,90,2,100,1,90,3,100,2,100,
+ 3,132,0,90,4,100,4,100,5,132,0,90,5,100,6,83,
+ 0,41,7,218,20,83,111,117,114,99,101,108,101,115,115,70,
+ 105,108,101,76,111,97,100,101,114,122,45,76,111,97,100,101,
+ 114,32,119,104,105,99,104,32,104,97,110,100,108,101,115,32,
+ 115,111,117,114,99,101,108,101,115,115,32,102,105,108,101,32,
+ 105,109,112,111,114,116,115,46,99,2,0,0,0,0,0,0,
+ 0,0,0,0,0,5,0,0,0,5,0,0,0,67,0,0,
+ 0,115,68,0,0,0,124,0,160,0,124,1,161,1,125,2,
+ 124,0,160,1,124,2,161,1,125,3,124,1,124,2,100,1,
+ 156,2,125,4,116,2,124,3,124,1,124,4,131,3,1,0,
+ 116,3,116,4,124,3,131,1,100,2,100,0,133,2,25,0,
+ 124,1,124,2,100,3,141,3,83,0,41,4,78,114,183,0,
+ 0,0,114,169,0,0,0,41,2,114,140,0,0,0,114,131,
+ 0,0,0,41,5,114,203,0,0,0,114,250,0,0,0,114,
+ 176,0,0,0,114,189,0,0,0,114,2,1,0,0,41,5,
+ 114,142,0,0,0,114,163,0,0,0,114,65,0,0,0,114,
+ 43,0,0,0,114,175,0,0,0,114,10,0,0,0,114,10,
+ 0,0,0,114,11,0,0,0,114,236,0,0,0,98,4,0,
+ 0,115,22,0,0,0,0,1,10,1,10,4,2,1,2,254,
+ 6,4,12,1,2,1,14,1,2,1,2,253,122,29,83,111,
+ 117,114,99,101,108,101,115,115,70,105,108,101,76,111,97,100,
+ 101,114,46,103,101,116,95,99,111,100,101,99,2,0,0,0,
+ 0,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,
+ 67,0,0,0,115,4,0,0,0,100,1,83,0,41,2,122,
+ 39,82,101,116,117,114,110,32,78,111,110,101,32,97,115,32,
+ 116,104,101,114,101,32,105,115,32,110,111,32,115,111,117,114,
+ 99,101,32,99,111,100,101,46,78,114,10,0,0,0,114,242,
+ 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,
+ 0,0,114,252,0,0,0,114,4,0,0,115,2,0,0,0,
+ 0,2,122,31,83,111,117,114,99,101,108,101,115,115,70,105,
+ 108,101,76,111,97,100,101,114,46,103,101,116,95,115,111,117,
+ 114,99,101,78,41,6,114,149,0,0,0,114,148,0,0,0,
+ 114,150,0,0,0,114,151,0,0,0,114,236,0,0,0,114,
+ 252,0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,
+ 0,0,0,114,11,0,0,0,114,39,1,0,0,94,4,0,
+ 0,115,6,0,0,0,8,2,4,2,8,16,114,39,1,0,
+ 0,99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,3,0,0,0,64,0,0,0,115,92,0,0,0,101,
+ 0,90,1,100,0,90,2,100,1,90,3,100,2,100,3,132,
+ 0,90,4,100,4,100,5,132,0,90,5,100,6,100,7,132,
+ 0,90,6,100,8,100,9,132,0,90,7,100,10,100,11,132,
+ 0,90,8,100,12,100,13,132,0,90,9,100,14,100,15,132,
+ 0,90,10,100,16,100,17,132,0,90,11,101,12,100,18,100,
+ 19,132,0,131,1,90,13,100,20,83,0,41,21,114,19,1,
+ 0,0,122,93,76,111,97,100,101,114,32,102,111,114,32,101,
+ 120,116,101,110,115,105,111,110,32,109,111,100,117,108,101,115,
+ 46,10,10,32,32,32,32,84,104,101,32,99,111,110,115,116,
+ 114,117,99,116,111,114,32,105,115,32,100,101,115,105,103,110,
+ 101,100,32,116,111,32,119,111,114,107,32,119,105,116,104,32,
+ 70,105,108,101,70,105,110,100,101,114,46,10,10,32,32,32,
+ 32,99,3,0,0,0,0,0,0,0,0,0,0,0,3,0,
+ 0,0,8,0,0,0,67,0,0,0,115,62,0,0,0,124,
+ 1,124,0,95,0,116,1,124,2,131,1,115,52,122,18,116,
+ 2,116,3,160,4,161,0,124,2,131,2,125,2,87,0,110,
+ 18,4,0,116,5,121,50,1,0,1,0,1,0,89,0,110,
+ 2,48,0,124,2,124,0,95,6,100,0,83,0,114,69,0,
+ 0,0,41,7,114,140,0,0,0,114,85,0,0,0,114,67,
+ 0,0,0,114,24,0,0,0,114,81,0,0,0,114,76,0,
+ 0,0,114,65,0,0,0,114,28,1,0,0,114,10,0,0,
+ 0,114,10,0,0,0,114,11,0,0,0,114,232,0,0,0,
+ 131,4,0,0,115,14,0,0,0,0,1,6,1,8,1,2,
+ 1,18,1,12,1,6,1,122,28,69,120,116,101,110,115,105,
+ 111,110,70,105,108,101,76,111,97,100,101,114,46,95,95,105,
+ 110,105,116,95,95,99,2,0,0,0,0,0,0,0,0,0,
+ 0,0,2,0,0,0,2,0,0,0,67,0,0,0,115,24,
+ 0,0,0,124,0,106,0,124,1,106,0,107,2,111,22,124,
+ 0,106,1,124,1,106,1,107,2,83,0,114,69,0,0,0,
+ 114,7,1,0,0,114,9,1,0,0,114,10,0,0,0,114,
+ 10,0,0,0,114,11,0,0,0,114,10,1,0,0,140,4,
+ 0,0,115,6,0,0,0,0,1,12,1,10,255,122,26,69,
+ 120,116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,
+ 101,114,46,95,95,101,113,95,95,99,1,0,0,0,0,0,
+ 0,0,0,0,0,0,1,0,0,0,3,0,0,0,67,0,
+ 0,0,115,20,0,0,0,116,0,124,0,106,1,131,1,116,
+ 0,124,0,106,2,131,1,65,0,83,0,114,69,0,0,0,
+ 114,11,1,0,0,114,13,1,0,0,114,10,0,0,0,114,
+ 10,0,0,0,114,11,0,0,0,114,14,1,0,0,144,4,
+ 0,0,115,2,0,0,0,0,1,122,28,69,120,116,101,110,
+ 115,105,111,110,70,105,108,101,76,111,97,100,101,114,46,95,
+ 95,104,97,115,104,95,95,99,2,0,0,0,0,0,0,0,
+ 0,0,0,0,3,0,0,0,5,0,0,0,67,0,0,0,
+ 115,36,0,0,0,116,0,160,1,116,2,106,3,124,1,161,
+ 2,125,2,116,0,160,4,100,1,124,1,106,5,124,0,106,
+ 6,161,3,1,0,124,2,83,0,41,2,122,38,67,114,101,
+ 97,116,101,32,97,110,32,117,110,105,116,105,97,108,105,122,
+ 101,100,32,101,120,116,101,110,115,105,111,110,32,109,111,100,
+ 117,108,101,122,38,101,120,116,101,110,115,105,111,110,32,109,
+ 111,100,117,108,101,32,123,33,114,125,32,108,111,97,100,101,
+ 100,32,102,114,111,109,32,123,33,114,125,41,7,114,158,0,
+ 0,0,114,237,0,0,0,114,187,0,0,0,90,14,99,114,
+ 101,97,116,101,95,100,121,110,97,109,105,99,114,173,0,0,
+ 0,114,140,0,0,0,114,65,0,0,0,41,3,114,142,0,
+ 0,0,114,210,0,0,0,114,239,0,0,0,114,10,0,0,
+ 0,114,10,0,0,0,114,11,0,0,0,114,235,0,0,0,
+ 147,4,0,0,115,14,0,0,0,0,2,4,1,6,255,4,
+ 2,6,1,8,255,4,2,122,33,69,120,116,101,110,115,105,
+ 111,110,70,105,108,101,76,111,97,100,101,114,46,99,114,101,
+ 97,116,101,95,109,111,100,117,108,101,99,2,0,0,0,0,
+ 0,0,0,0,0,0,0,2,0,0,0,5,0,0,0,67,
+ 0,0,0,115,36,0,0,0,116,0,160,1,116,2,106,3,
+ 124,1,161,2,1,0,116,0,160,4,100,1,124,0,106,5,
+ 124,0,106,6,161,3,1,0,100,2,83,0,41,3,122,30,
+ 73,110,105,116,105,97,108,105,122,101,32,97,110,32,101,120,
+ 116,101,110,115,105,111,110,32,109,111,100,117,108,101,122,40,
+ 101,120,116,101,110,115,105,111,110,32,109,111,100,117,108,101,
+ 32,123,33,114,125,32,101,120,101,99,117,116,101,100,32,102,
+ 114,111,109,32,123,33,114,125,78,41,7,114,158,0,0,0,
+ 114,237,0,0,0,114,187,0,0,0,90,12,101,120,101,99,
+ 95,100,121,110,97,109,105,99,114,173,0,0,0,114,140,0,
+ 0,0,114,65,0,0,0,114,20,1,0,0,114,10,0,0,
+ 0,114,10,0,0,0,114,11,0,0,0,114,240,0,0,0,
+ 155,4,0,0,115,8,0,0,0,0,2,14,1,6,1,8,
+ 255,122,31,69,120,116,101,110,115,105,111,110,70,105,108,101,
+ 76,111,97,100,101,114,46,101,120,101,99,95,109,111,100,117,
+ 108,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2,
+ 0,0,0,4,0,0,0,3,0,0,0,115,36,0,0,0,
+ 116,0,124,0,106,1,131,1,100,1,25,0,137,0,116,2,
+ 135,0,102,1,100,2,100,3,132,8,116,3,68,0,131,1,
+ 131,1,83,0,41,4,122,49,82,101,116,117,114,110,32,84,
+ 114,117,101,32,105,102,32,116,104,101,32,101,120,116,101,110,
+ 115,105,111,110,32,109,111,100,117,108,101,32,105,115,32,97,
+ 32,112,97,99,107,97,103,101,46,114,4,0,0,0,99,1,
+ 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,4,
+ 0,0,0,51,0,0,0,115,26,0,0,0,124,0,93,18,
+ 125,1,136,0,100,0,124,1,23,0,107,2,86,0,1,0,
+ 113,2,100,1,83,0,41,2,114,232,0,0,0,78,114,10,
+ 0,0,0,169,2,114,8,0,0,0,218,6,115,117,102,102,
+ 105,120,169,1,90,9,102,105,108,101,95,110,97,109,101,114,
+ 10,0,0,0,114,11,0,0,0,114,12,0,0,0,164,4,
+ 0,0,115,4,0,0,0,4,1,2,255,122,49,69,120,116,
+ 101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,114,
+ 46,105,115,95,112,97,99,107,97,103,101,46,60,108,111,99,
+ 97,108,115,62,46,60,103,101,110,101,120,112,114,62,41,4,
+ 114,74,0,0,0,114,65,0,0,0,218,3,97,110,121,218,
+ 18,69,88,84,69,78,83,73,79,78,95,83,85,70,70,73,
+ 88,69,83,114,242,0,0,0,114,10,0,0,0,114,42,1,
+ 0,0,114,11,0,0,0,114,206,0,0,0,161,4,0,0,
+ 115,8,0,0,0,0,2,14,1,12,1,2,255,122,30,69,
+ 120,116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,
+ 101,114,46,105,115,95,112,97,99,107,97,103,101,99,2,0,
+ 0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,0,
+ 0,0,67,0,0,0,115,4,0,0,0,100,1,83,0,41,
+ 2,122,63,82,101,116,117,114,110,32,78,111,110,101,32,97,
+ 115,32,97,110,32,101,120,116,101,110,115,105,111,110,32,109,
+ 111,100,117,108,101,32,99,97,110,110,111,116,32,99,114,101,
+ 97,116,101,32,97,32,99,111,100,101,32,111,98,106,101,99,
+ 116,46,78,114,10,0,0,0,114,242,0,0,0,114,10,0,
+ 0,0,114,10,0,0,0,114,11,0,0,0,114,236,0,0,
+ 0,167,4,0,0,115,2,0,0,0,0,2,122,28,69,120,
+ 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,
+ 114,46,103,101,116,95,99,111,100,101,99,2,0,0,0,0,
+ 0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,67,
+ 0,0,0,115,4,0,0,0,100,1,83,0,41,2,122,53,
+ 82,101,116,117,114,110,32,78,111,110,101,32,97,115,32,101,
+ 120,116,101,110,115,105,111,110,32,109,111,100,117,108,101,115,
+ 32,104,97,118,101,32,110,111,32,115,111,117,114,99,101,32,
+ 99,111,100,101,46,78,114,10,0,0,0,114,242,0,0,0,
+ 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,
+ 252,0,0,0,171,4,0,0,115,2,0,0,0,0,2,122,
+ 30,69,120,116,101,110,115,105,111,110,70,105,108,101,76,111,
+ 97,100,101,114,46,103,101,116,95,115,111,117,114,99,101,99,
+ 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,
+ 1,0,0,0,67,0,0,0,115,6,0,0,0,124,0,106,
+ 0,83,0,114,17,1,0,0,114,71,0,0,0,114,242,0,
+ 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+ 0,114,203,0,0,0,175,4,0,0,115,2,0,0,0,0,
+ 3,122,32,69,120,116,101,110,115,105,111,110,70,105,108,101,
+ 76,111,97,100,101,114,46,103,101,116,95,102,105,108,101,110,
+ 97,109,101,78,41,14,114,149,0,0,0,114,148,0,0,0,
+ 114,150,0,0,0,114,151,0,0,0,114,232,0,0,0,114,
+ 10,1,0,0,114,14,1,0,0,114,235,0,0,0,114,240,
+ 0,0,0,114,206,0,0,0,114,236,0,0,0,114,252,0,
+ 0,0,114,160,0,0,0,114,203,0,0,0,114,10,0,0,
+ 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
+ 114,19,1,0,0,123,4,0,0,115,22,0,0,0,8,2,
+ 4,6,8,9,8,4,8,3,8,8,8,6,8,6,8,4,
+ 8,4,2,1,114,19,1,0,0,99,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,2,0,0,0,64,0,
+ 0,0,115,104,0,0,0,101,0,90,1,100,0,90,2,100,
+ 1,90,3,100,2,100,3,132,0,90,4,100,4,100,5,132,
+ 0,90,5,100,6,100,7,132,0,90,6,100,8,100,9,132,
+ 0,90,7,100,10,100,11,132,0,90,8,100,12,100,13,132,
+ 0,90,9,100,14,100,15,132,0,90,10,100,16,100,17,132,
+ 0,90,11,100,18,100,19,132,0,90,12,100,20,100,21,132,
+ 0,90,13,100,22,100,23,132,0,90,14,100,24,83,0,41,
+ 25,218,14,95,78,97,109,101,115,112,97,99,101,80,97,116,
+ 104,97,38,1,0,0,82,101,112,114,101,115,101,110,116,115,
+ 32,97,32,110,97,109,101,115,112,97,99,101,32,112,97,99,
+ 107,97,103,101,39,115,32,112,97,116,104,46,32,32,73,116,
+ 32,117,115,101,115,32,116,104,101,32,109,111,100,117,108,101,
+ 32,110,97,109,101,10,32,32,32,32,116,111,32,102,105,110,
+ 100,32,105,116,115,32,112,97,114,101,110,116,32,109,111,100,
+ 117,108,101,44,32,97,110,100,32,102,114,111,109,32,116,104,
+ 101,114,101,32,105,116,32,108,111,111,107,115,32,117,112,32,
+ 116,104,101,32,112,97,114,101,110,116,39,115,10,32,32,32,
+ 32,95,95,112,97,116,104,95,95,46,32,32,87,104,101,110,
+ 32,116,104,105,115,32,99,104,97,110,103,101,115,44,32,116,
+ 104,101,32,109,111,100,117,108,101,39,115,32,111,119,110,32,
+ 112,97,116,104,32,105,115,32,114,101,99,111,109,112,117,116,
+ 101,100,44,10,32,32,32,32,117,115,105,110,103,32,112,97,
+ 116,104,95,102,105,110,100,101,114,46,32,32,70,111,114,32,
+ 116,111,112,45,108,101,118,101,108,32,109,111,100,117,108,101,
+ 115,44,32,116,104,101,32,112,97,114,101,110,116,32,109,111,
+ 100,117,108,101,39,115,32,112,97,116,104,10,32,32,32,32,
+ 105,115,32,115,121,115,46,112,97,116,104,46,99,4,0,0,
+ 0,0,0,0,0,0,0,0,0,4,0,0,0,3,0,0,
+ 0,67,0,0,0,115,36,0,0,0,124,1,124,0,95,0,
+ 124,2,124,0,95,1,116,2,124,0,160,3,161,0,131,1,
+ 124,0,95,4,124,3,124,0,95,5,100,0,83,0,114,69,
+ 0,0,0,41,6,218,5,95,110,97,109,101,218,5,95,112,
+ 97,116,104,114,135,0,0,0,218,16,95,103,101,116,95,112,
+ 97,114,101,110,116,95,112,97,116,104,218,17,95,108,97,115,
+ 116,95,112,97,114,101,110,116,95,112,97,116,104,218,12,95,
+ 112,97,116,104,95,102,105,110,100,101,114,169,4,114,142,0,
+ 0,0,114,140,0,0,0,114,65,0,0,0,90,11,112,97,
+ 116,104,95,102,105,110,100,101,114,114,10,0,0,0,114,10,
+ 0,0,0,114,11,0,0,0,114,232,0,0,0,188,4,0,
+ 0,115,8,0,0,0,0,1,6,1,6,1,14,1,122,23,
+ 95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,
+ 95,105,110,105,116,95,95,99,1,0,0,0,0,0,0,0,
+ 0,0,0,0,4,0,0,0,3,0,0,0,67,0,0,0,
+ 115,38,0,0,0,124,0,106,0,160,1,100,1,161,1,92,
+ 3,125,1,125,2,125,3,124,2,100,2,107,2,114,30,100,
+ 3,83,0,124,1,100,4,102,2,83,0,41,5,122,62,82,
+ 101,116,117,114,110,115,32,97,32,116,117,112,108,101,32,111,
+ 102,32,40,112,97,114,101,110,116,45,109,111,100,117,108,101,
+ 45,110,97,109,101,44,32,112,97,114,101,110,116,45,112,97,
+ 116,104,45,97,116,116,114,45,110,97,109,101,41,114,96,0,
+ 0,0,114,14,0,0,0,41,2,114,21,0,0,0,114,65,
+ 0,0,0,90,8,95,95,112,97,116,104,95,95,41,2,114,
+ 46,1,0,0,114,103,0,0,0,41,4,114,142,0,0,0,
+ 114,38,1,0,0,218,3,100,111,116,90,2,109,101,114,10,
+ 0,0,0,114,10,0,0,0,114,11,0,0,0,218,23,95,
+ 102,105,110,100,95,112,97,114,101,110,116,95,112,97,116,104,
+ 95,110,97,109,101,115,194,4,0,0,115,8,0,0,0,0,
+ 2,18,1,8,2,4,3,122,38,95,78,97,109,101,115,112,
+ 97,99,101,80,97,116,104,46,95,102,105,110,100,95,112,97,
+ 114,101,110,116,95,112,97,116,104,95,110,97,109,101,115,99,
+ 1,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,
+ 3,0,0,0,67,0,0,0,115,28,0,0,0,124,0,160,
+ 0,161,0,92,2,125,1,125,2,116,1,116,2,106,3,124,
+ 1,25,0,124,2,131,2,83,0,114,69,0,0,0,41,4,
+ 114,53,1,0,0,114,154,0,0,0,114,21,0,0,0,218,
+ 7,109,111,100,117,108,101,115,41,3,114,142,0,0,0,90,
+ 18,112,97,114,101,110,116,95,109,111,100,117,108,101,95,110,
+ 97,109,101,90,14,112,97,116,104,95,97,116,116,114,95,110,
+ 97,109,101,114,10,0,0,0,114,10,0,0,0,114,11,0,
+ 0,0,114,48,1,0,0,204,4,0,0,115,4,0,0,0,
+ 0,1,12,1,122,31,95,78,97,109,101,115,112,97,99,101,
+ 80,97,116,104,46,95,103,101,116,95,112,97,114,101,110,116,
+ 95,112,97,116,104,99,1,0,0,0,0,0,0,0,0,0,
+ 0,0,3,0,0,0,4,0,0,0,67,0,0,0,115,80,
+ 0,0,0,116,0,124,0,160,1,161,0,131,1,125,1,124,
+ 1,124,0,106,2,107,3,114,74,124,0,160,3,124,0,106,
+ 4,124,1,161,2,125,2,124,2,100,0,117,1,114,68,124,
+ 2,106,5,100,0,117,0,114,68,124,2,106,6,114,68,124,
+ 2,106,6,124,0,95,7,124,1,124,0,95,2,124,0,106,
+ 7,83,0,114,69,0,0,0,41,8,114,135,0,0,0,114,
+ 48,1,0,0,114,49,1,0,0,114,50,1,0,0,114,46,
+ 1,0,0,114,164,0,0,0,114,202,0,0,0,114,47,1,
+ 0,0,41,3,114,142,0,0,0,90,11,112,97,114,101,110,
+ 116,95,112,97,116,104,114,210,0,0,0,114,10,0,0,0,
+ 114,10,0,0,0,114,11,0,0,0,218,12,95,114,101,99,
+ 97,108,99,117,108,97,116,101,208,4,0,0,115,16,0,0,
+ 0,0,2,12,1,10,1,14,3,18,1,6,1,8,1,6,
+ 1,122,27,95,78,97,109,101,115,112,97,99,101,80,97,116,
+ 104,46,95,114,101,99,97,108,99,117,108,97,116,101,99,1,
+ 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,3,
+ 0,0,0,67,0,0,0,115,12,0,0,0,116,0,124,0,
+ 160,1,161,0,131,1,83,0,114,69,0,0,0,41,2,114,
+ 29,1,0,0,114,55,1,0,0,114,13,1,0,0,114,10,
+ 0,0,0,114,10,0,0,0,114,11,0,0,0,218,8,95,
+ 95,105,116,101,114,95,95,221,4,0,0,115,2,0,0,0,
+ 0,1,122,23,95,78,97,109,101,115,112,97,99,101,80,97,
+ 116,104,46,95,95,105,116,101,114,95,95,99,2,0,0,0,
+ 0,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,
+ 67,0,0,0,115,12,0,0,0,124,0,160,0,161,0,124,
+ 1,25,0,83,0,114,69,0,0,0,169,1,114,55,1,0,
+ 0,41,2,114,142,0,0,0,218,5,105,110,100,101,120,114,
+ 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,11,
+ 95,95,103,101,116,105,116,101,109,95,95,224,4,0,0,115,
+ 2,0,0,0,0,1,122,26,95,78,97,109,101,115,112,97,
+ 99,101,80,97,116,104,46,95,95,103,101,116,105,116,101,109,
+ 95,95,99,3,0,0,0,0,0,0,0,0,0,0,0,3,
+ 0,0,0,3,0,0,0,67,0,0,0,115,14,0,0,0,
+ 124,2,124,0,106,0,124,1,60,0,100,0,83,0,114,69,
+ 0,0,0,41,1,114,47,1,0,0,41,3,114,142,0,0,
+ 0,114,58,1,0,0,114,65,0,0,0,114,10,0,0,0,
+ 114,10,0,0,0,114,11,0,0,0,218,11,95,95,115,101,
+ 116,105,116,101,109,95,95,227,4,0,0,115,2,0,0,0,
+ 0,1,122,26,95,78,97,109,101,115,112,97,99,101,80,97,
+ 116,104,46,95,95,115,101,116,105,116,101,109,95,95,99,1,
+ 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,3,
+ 0,0,0,67,0,0,0,115,12,0,0,0,116,0,124,0,
+ 160,1,161,0,131,1,83,0,114,69,0,0,0,41,2,114,
+ 6,0,0,0,114,55,1,0,0,114,13,1,0,0,114,10,
+ 0,0,0,114,10,0,0,0,114,11,0,0,0,218,7,95,
+ 95,108,101,110,95,95,230,4,0,0,115,2,0,0,0,0,
+ 1,122,22,95,78,97,109,101,115,112,97,99,101,80,97,116,
+ 104,46,95,95,108,101,110,95,95,99,1,0,0,0,0,0,
+ 0,0,0,0,0,0,1,0,0,0,3,0,0,0,67,0,
+ 0,0,115,12,0,0,0,100,1,160,0,124,0,106,1,161,
+ 1,83,0,41,2,78,122,20,95,78,97,109,101,115,112,97,
+ 99,101,80,97,116,104,40,123,33,114,125,41,41,2,114,88,
+ 0,0,0,114,47,1,0,0,114,13,1,0,0,114,10,0,
+ 0,0,114,10,0,0,0,114,11,0,0,0,218,8,95,95,
+ 114,101,112,114,95,95,233,4,0,0,115,2,0,0,0,0,
+ 1,122,23,95,78,97,109,101,115,112,97,99,101,80,97,116,
+ 104,46,95,95,114,101,112,114,95,95,99,2,0,0,0,0,
+ 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,67,
+ 0,0,0,115,12,0,0,0,124,1,124,0,160,0,161,0,
+ 118,0,83,0,114,69,0,0,0,114,57,1,0,0,169,2,
+ 114,142,0,0,0,218,4,105,116,101,109,114,10,0,0,0,
+ 114,10,0,0,0,114,11,0,0,0,218,12,95,95,99,111,
+ 110,116,97,105,110,115,95,95,236,4,0,0,115,2,0,0,
+ 0,0,1,122,27,95,78,97,109,101,115,112,97,99,101,80,
+ 97,116,104,46,95,95,99,111,110,116,97,105,110,115,95,95,
+ 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,
+ 0,3,0,0,0,67,0,0,0,115,16,0,0,0,124,0,
+ 106,0,160,1,124,1,161,1,1,0,100,0,83,0,114,69,
+ 0,0,0,41,2,114,47,1,0,0,114,61,0,0,0,114,
+ 63,1,0,0,114,10,0,0,0,114,10,0,0,0,114,11,
+ 0,0,0,114,61,0,0,0,239,4,0,0,115,2,0,0,
+ 0,0,1,122,21,95,78,97,109,101,115,112,97,99,101,80,
+ 97,116,104,46,97,112,112,101,110,100,78,41,15,114,149,0,
+ 0,0,114,148,0,0,0,114,150,0,0,0,114,151,0,0,
+ 0,114,232,0,0,0,114,53,1,0,0,114,48,1,0,0,
+ 114,55,1,0,0,114,56,1,0,0,114,59,1,0,0,114,
+ 60,1,0,0,114,61,1,0,0,114,62,1,0,0,114,65,
+ 1,0,0,114,61,0,0,0,114,10,0,0,0,114,10,0,
+ 0,0,114,10,0,0,0,114,11,0,0,0,114,45,1,0,
+ 0,181,4,0,0,115,24,0,0,0,8,1,4,6,8,6,
+ 8,10,8,4,8,13,8,3,8,3,8,3,8,3,8,3,
+ 8,3,114,45,1,0,0,99,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,3,0,0,0,64,0,0,0,
+ 115,80,0,0,0,101,0,90,1,100,0,90,2,100,1,100,
+ 2,132,0,90,3,101,4,100,3,100,4,132,0,131,1,90,
+ 5,100,5,100,6,132,0,90,6,100,7,100,8,132,0,90,
+ 7,100,9,100,10,132,0,90,8,100,11,100,12,132,0,90,
+ 9,100,13,100,14,132,0,90,10,100,15,100,16,132,0,90,
+ 11,100,17,83,0,41,18,218,16,95,78,97,109,101,115,112,
+ 97,99,101,76,111,97,100,101,114,99,4,0,0,0,0,0,
+ 0,0,0,0,0,0,4,0,0,0,4,0,0,0,67,0,
+ 0,0,115,18,0,0,0,116,0,124,1,124,2,124,3,131,
+ 3,124,0,95,1,100,0,83,0,114,69,0,0,0,41,2,
+ 114,45,1,0,0,114,47,1,0,0,114,51,1,0,0,114,
+ 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,232,
+ 0,0,0,245,4,0,0,115,2,0,0,0,0,1,122,25,
+ 95,78,97,109,101,115,112,97,99,101,76,111,97,100,101,114,
+ 46,95,95,105,110,105,116,95,95,99,2,0,0,0,0,0,
+ 0,0,0,0,0,0,2,0,0,0,3,0,0,0,67,0,
+ 0,0,115,12,0,0,0,100,1,160,0,124,1,106,1,161,
+ 1,83,0,41,2,122,115,82,101,116,117,114,110,32,114,101,
+ 112,114,32,102,111,114,32,116,104,101,32,109,111,100,117,108,
+ 101,46,10,10,32,32,32,32,32,32,32,32,84,104,101,32,
+ 109,101,116,104,111,100,32,105,115,32,100,101,112,114,101,99,
+ 97,116,101,100,46,32,32,84,104,101,32,105,109,112,111,114,
+ 116,32,109,97,99,104,105,110,101,114,121,32,100,111,101,115,
+ 32,116,104,101,32,106,111,98,32,105,116,115,101,108,102,46,
+ 10,10,32,32,32,32,32,32,32,32,122,25,60,109,111,100,
+ 117,108,101,32,123,33,114,125,32,40,110,97,109,101,115,112,
+ 97,99,101,41,62,41,2,114,88,0,0,0,114,149,0,0,
+ 0,41,2,114,216,0,0,0,114,239,0,0,0,114,10,0,
+ 0,0,114,10,0,0,0,114,11,0,0,0,218,11,109,111,
+ 100,117,108,101,95,114,101,112,114,248,4,0,0,115,2,0,
+ 0,0,0,7,122,28,95,78,97,109,101,115,112,97,99,101,
+ 76,111,97,100,101,114,46,109,111,100,117,108,101,95,114,101,
+ 112,114,99,2,0,0,0,0,0,0,0,0,0,0,0,2,
+ 0,0,0,1,0,0,0,67,0,0,0,115,4,0,0,0,
+ 100,1,83,0,41,2,78,84,114,10,0,0,0,114,242,0,
+ 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+ 0,114,206,0,0,0,1,5,0,0,115,2,0,0,0,0,
+ 1,122,27,95,78,97,109,101,115,112,97,99,101,76,111,97,
+ 100,101,114,46,105,115,95,112,97,99,107,97,103,101,99,2,
+ 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,
+ 0,0,0,67,0,0,0,115,4,0,0,0,100,1,83,0,
+ 41,2,78,114,14,0,0,0,114,10,0,0,0,114,242,0,
+ 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+ 0,114,252,0,0,0,4,5,0,0,115,2,0,0,0,0,
+ 1,122,27,95,78,97,109,101,115,112,97,99,101,76,111,97,
+ 100,101,114,46,103,101,116,95,115,111,117,114,99,101,99,2,
+ 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,6,
+ 0,0,0,67,0,0,0,115,16,0,0,0,116,0,100,1,
+ 100,2,100,3,100,4,100,5,141,4,83,0,41,6,78,114,
+ 14,0,0,0,122,8,60,115,116,114,105,110,103,62,114,238,
+ 0,0,0,84,41,1,114,254,0,0,0,41,1,114,255,0,
+ 0,0,114,242,0,0,0,114,10,0,0,0,114,10,0,0,
+ 0,114,11,0,0,0,114,236,0,0,0,7,5,0,0,115,
+ 2,0,0,0,0,1,122,25,95,78,97,109,101,115,112,97,
+ 99,101,76,111,97,100,101,114,46,103,101,116,95,99,111,100,
+ 101,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,
+ 0,0,1,0,0,0,67,0,0,0,115,4,0,0,0,100,
+ 1,83,0,114,233,0,0,0,114,10,0,0,0,114,234,0,
+ 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+ 0,114,235,0,0,0,10,5,0,0,115,2,0,0,0,0,
+ 1,122,30,95,78,97,109,101,115,112,97,99,101,76,111,97,
+ 100,101,114,46,99,114,101,97,116,101,95,109,111,100,117,108,
+ 101,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,
+ 0,0,1,0,0,0,67,0,0,0,115,4,0,0,0,100,
+ 0,83,0,114,69,0,0,0,114,10,0,0,0,114,20,1,
+ 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+ 0,114,240,0,0,0,13,5,0,0,115,2,0,0,0,0,
+ 1,122,28,95,78,97,109,101,115,112,97,99,101,76,111,97,
+ 100,101,114,46,101,120,101,99,95,109,111,100,117,108,101,99,
+ 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,
+ 4,0,0,0,67,0,0,0,115,26,0,0,0,116,0,160,
+ 1,100,1,124,0,106,2,161,2,1,0,116,0,160,3,124,
+ 0,124,1,161,2,83,0,41,2,122,98,76,111,97,100,32,
+ 97,32,110,97,109,101,115,112,97,99,101,32,109,111,100,117,
+ 108,101,46,10,10,32,32,32,32,32,32,32,32,84,104,105,
+ 115,32,109,101,116,104,111,100,32,105,115,32,100,101,112,114,
+ 101,99,97,116,101,100,46,32,32,85,115,101,32,101,120,101,
+ 99,95,109,111,100,117,108,101,40,41,32,105,110,115,116,101,
+ 97,100,46,10,10,32,32,32,32,32,32,32,32,122,38,110,
+ 97,109,101,115,112,97,99,101,32,109,111,100,117,108,101,32,
+ 108,111,97,100,101,100,32,119,105,116,104,32,112,97,116,104,
+ 32,123,33,114,125,41,4,114,158,0,0,0,114,173,0,0,
+ 0,114,47,1,0,0,114,241,0,0,0,114,242,0,0,0,
+ 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,
+ 243,0,0,0,16,5,0,0,115,8,0,0,0,0,7,6,
+ 1,4,255,4,2,122,28,95,78,97,109,101,115,112,97,99,
+ 101,76,111,97,100,101,114,46,108,111,97,100,95,109,111,100,
+ 117,108,101,78,41,12,114,149,0,0,0,114,148,0,0,0,
+ 114,150,0,0,0,114,232,0,0,0,114,230,0,0,0,114,
+ 67,1,0,0,114,206,0,0,0,114,252,0,0,0,114,236,
+ 0,0,0,114,235,0,0,0,114,240,0,0,0,114,243,0,
+ 0,0,114,10,0,0,0,114,10,0,0,0,114,10,0,0,
+ 0,114,11,0,0,0,114,66,1,0,0,244,4,0,0,115,
+ 18,0,0,0,8,1,8,3,2,1,10,8,8,3,8,3,
+ 8,3,8,3,8,3,114,66,1,0,0,99,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,
+ 64,0,0,0,115,118,0,0,0,101,0,90,1,100,0,90,
+ 2,100,1,90,3,101,4,100,2,100,3,132,0,131,1,90,
+ 5,101,4,100,4,100,5,132,0,131,1,90,6,101,4,100,
+ 6,100,7,132,0,131,1,90,7,101,4,100,8,100,9,132,
+ 0,131,1,90,8,101,4,100,19,100,11,100,12,132,1,131,
+ 1,90,9,101,4,100,20,100,13,100,14,132,1,131,1,90,
+ 10,101,4,100,21,100,15,100,16,132,1,131,1,90,11,101,
+ 4,100,17,100,18,132,0,131,1,90,12,100,10,83,0,41,
+ 22,218,10,80,97,116,104,70,105,110,100,101,114,122,62,77,
+ 101,116,97,32,112,97,116,104,32,102,105,110,100,101,114,32,
+ 102,111,114,32,115,121,115,46,112,97,116,104,32,97,110,100,
+ 32,112,97,99,107,97,103,101,32,95,95,112,97,116,104,95,
+ 95,32,97,116,116,114,105,98,117,116,101,115,46,99,1,0,
+ 0,0,0,0,0,0,0,0,0,0,3,0,0,0,4,0,
+ 0,0,67,0,0,0,115,64,0,0,0,116,0,116,1,106,
+ 2,160,3,161,0,131,1,68,0,93,44,92,2,125,1,125,
+ 2,124,2,100,1,117,0,114,40,116,1,106,2,124,1,61,
+ 0,113,14,116,4,124,2,100,2,131,2,114,14,124,2,160,
+ 5,161,0,1,0,113,14,100,1,83,0,41,3,122,125,67,
+ 97,108,108,32,116,104,101,32,105,110,118,97,108,105,100,97,
+ 116,101,95,99,97,99,104,101,115,40,41,32,109,101,116,104,
+ 111,100,32,111,110,32,97,108,108,32,112,97,116,104,32,101,
+ 110,116,114,121,32,102,105,110,100,101,114,115,10,32,32,32,
+ 32,32,32,32,32,115,116,111,114,101,100,32,105,110,32,115,
+ 121,115,46,112,97,116,104,95,105,109,112,111,114,116,101,114,
+ 95,99,97,99,104,101,115,32,40,119,104,101,114,101,32,105,
+ 109,112,108,101,109,101,110,116,101,100,41,46,78,218,17,105,
+ 110,118,97,108,105,100,97,116,101,95,99,97,99,104,101,115,
+ 41,6,218,4,108,105,115,116,114,21,0,0,0,218,19,112,
+ 97,116,104,95,105,109,112,111,114,116,101,114,95,99,97,99,
+ 104,101,218,5,105,116,101,109,115,114,152,0,0,0,114,69,
+ 1,0,0,41,3,114,216,0,0,0,114,140,0,0,0,218,
+ 6,102,105,110,100,101,114,114,10,0,0,0,114,10,0,0,
+ 0,114,11,0,0,0,114,69,1,0,0,34,5,0,0,115,
+ 10,0,0,0,0,4,22,1,8,1,10,1,10,1,122,28,
+ 80,97,116,104,70,105,110,100,101,114,46,105,110,118,97,108,
+ 105,100,97,116,101,95,99,97,99,104,101,115,99,2,0,0,
+ 0,0,0,0,0,0,0,0,0,3,0,0,0,9,0,0,
+ 0,67,0,0,0,115,82,0,0,0,116,0,106,1,100,1,
+ 117,1,114,28,116,0,106,1,115,28,116,2,160,3,100,2,
+ 116,4,161,2,1,0,116,0,106,1,68,0,93,42,125,2,
+ 122,14,124,2,124,1,131,1,87,0,2,0,1,0,83,0,
+ 4,0,116,5,121,74,1,0,1,0,1,0,89,0,113,34,
+ 89,0,113,34,48,0,113,34,100,1,83,0,41,3,122,46,
+ 83,101,97,114,99,104,32,115,121,115,46,112,97,116,104,95,
+ 104,111,111,107,115,32,102,111,114,32,97,32,102,105,110,100,
+ 101,114,32,102,111,114,32,39,112,97,116,104,39,46,78,122,
+ 23,115,121,115,46,112,97,116,104,95,104,111,111,107,115,32,
+ 105,115,32,101,109,112,116,121,41,6,114,21,0,0,0,218,
+ 10,112,97,116,104,95,104,111,111,107,115,114,98,0,0,0,
+ 114,99,0,0,0,114,162,0,0,0,114,141,0,0,0,41,
+ 3,114,216,0,0,0,114,65,0,0,0,90,4,104,111,111,
+ 107,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
+ 218,11,95,112,97,116,104,95,104,111,111,107,115,44,5,0,
+ 0,115,16,0,0,0,0,3,16,1,12,1,10,1,2,1,
+ 14,1,12,1,12,2,122,22,80,97,116,104,70,105,110,100,
+ 101,114,46,95,112,97,116,104,95,104,111,111,107,115,99,2,
+ 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,8,
+ 0,0,0,67,0,0,0,115,100,0,0,0,124,1,100,1,
+ 107,2,114,42,122,12,116,0,160,1,161,0,125,1,87,0,
+ 110,20,4,0,116,2,121,40,1,0,1,0,1,0,89,0,
+ 100,2,83,0,48,0,122,14,116,3,106,4,124,1,25,0,
+ 125,2,87,0,110,38,4,0,116,5,121,94,1,0,1,0,
+ 1,0,124,0,160,6,124,1,161,1,125,2,124,2,116,3,
+ 106,4,124,1,60,0,89,0,110,2,48,0,124,2,83,0,
+ 41,3,122,210,71,101,116,32,116,104,101,32,102,105,110,100,
+ 101,114,32,102,111,114,32,116,104,101,32,112,97,116,104,32,
+ 101,110,116,114,121,32,102,114,111,109,32,115,121,115,46,112,
+ 97,116,104,95,105,109,112,111,114,116,101,114,95,99,97,99,
+ 104,101,46,10,10,32,32,32,32,32,32,32,32,73,102,32,
+ 116,104,101,32,112,97,116,104,32,101,110,116,114,121,32,105,
+ 115,32,110,111,116,32,105,110,32,116,104,101,32,99,97,99,
+ 104,101,44,32,102,105,110,100,32,116,104,101,32,97,112,112,
+ 114,111,112,114,105,97,116,101,32,102,105,110,100,101,114,10,
+ 32,32,32,32,32,32,32,32,97,110,100,32,99,97,99,104,
+ 101,32,105,116,46,32,73,102,32,110,111,32,102,105,110,100,
+ 101,114,32,105,115,32,97,118,97,105,108,97,98,108,101,44,
+ 32,115,116,111,114,101,32,78,111,110,101,46,10,10,32,32,
+ 32,32,32,32,32,32,114,14,0,0,0,78,41,7,114,24,
+ 0,0,0,114,81,0,0,0,114,26,1,0,0,114,21,0,
+ 0,0,114,71,1,0,0,218,8,75,101,121,69,114,114,111,
+ 114,114,75,1,0,0,41,3,114,216,0,0,0,114,65,0,
+ 0,0,114,73,1,0,0,114,10,0,0,0,114,10,0,0,
+ 0,114,11,0,0,0,218,20,95,112,97,116,104,95,105,109,
+ 112,111,114,116,101,114,95,99,97,99,104,101,57,5,0,0,
+ 115,22,0,0,0,0,8,8,1,2,1,12,1,12,3,8,
+ 1,2,1,14,1,12,1,10,1,16,1,122,31,80,97,116,
+ 104,70,105,110,100,101,114,46,95,112,97,116,104,95,105,109,
+ 112,111,114,116,101,114,95,99,97,99,104,101,99,3,0,0,
+ 0,0,0,0,0,0,0,0,0,6,0,0,0,4,0,0,
+ 0,67,0,0,0,115,82,0,0,0,116,0,124,2,100,1,
+ 131,2,114,26,124,2,160,1,124,1,161,1,92,2,125,3,
+ 125,4,110,14,124,2,160,2,124,1,161,1,125,3,103,0,
+ 125,4,124,3,100,0,117,1,114,60,116,3,160,4,124,1,
+ 124,3,161,2,83,0,116,3,160,5,124,1,100,0,161,2,
+ 125,5,124,4,124,5,95,6,124,5,83,0,41,2,78,114,
+ 161,0,0,0,41,7,114,152,0,0,0,114,161,0,0,0,
+ 114,229,0,0,0,114,158,0,0,0,114,224,0,0,0,114,
+ 207,0,0,0,114,202,0,0,0,41,6,114,216,0,0,0,
+ 114,163,0,0,0,114,73,1,0,0,114,164,0,0,0,114,
+ 165,0,0,0,114,210,0,0,0,114,10,0,0,0,114,10,
+ 0,0,0,114,11,0,0,0,218,16,95,108,101,103,97,99,
+ 121,95,103,101,116,95,115,112,101,99,79,5,0,0,115,18,
+ 0,0,0,0,4,10,1,16,2,10,1,4,1,8,1,12,
+ 1,12,1,6,1,122,27,80,97,116,104,70,105,110,100,101,
+ 114,46,95,108,101,103,97,99,121,95,103,101,116,95,115,112,
+ 101,99,78,99,4,0,0,0,0,0,0,0,0,0,0,0,
+ 9,0,0,0,5,0,0,0,67,0,0,0,115,166,0,0,
+ 0,103,0,125,4,124,2,68,0,93,134,125,5,116,0,124,
+ 5,116,1,116,2,102,2,131,2,115,28,113,8,124,0,160,
+ 3,124,5,161,1,125,6,124,6,100,1,117,1,114,8,116,
+ 4,124,6,100,2,131,2,114,70,124,6,160,5,124,1,124,
+ 3,161,2,125,7,110,12,124,0,160,6,124,1,124,6,161,
+ 2,125,7,124,7,100,1,117,0,114,92,113,8,124,7,106,
+ 7,100,1,117,1,114,110,124,7,2,0,1,0,83,0,124,
+ 7,106,8,125,8,124,8,100,1,117,0,114,132,116,9,100,
+ 3,131,1,130,1,124,4,160,10,124,8,161,1,1,0,113,
+ 8,116,11,160,12,124,1,100,1,161,2,125,7,124,4,124,
+ 7,95,8,124,7,83,0,41,4,122,63,70,105,110,100,32,
+ 116,104,101,32,108,111,97,100,101,114,32,111,114,32,110,97,
+ 109,101,115,112,97,99,101,95,112,97,116,104,32,102,111,114,
+ 32,116,104,105,115,32,109,111,100,117,108,101,47,112,97,99,
+ 107,97,103,101,32,110,97,109,101,46,78,114,226,0,0,0,
+ 122,19,115,112,101,99,32,109,105,115,115,105,110,103,32,108,
+ 111,97,100,101,114,41,13,114,185,0,0,0,114,108,0,0,
+ 0,218,5,98,121,116,101,115,114,77,1,0,0,114,152,0,
+ 0,0,114,226,0,0,0,114,78,1,0,0,114,164,0,0,
+ 0,114,202,0,0,0,114,141,0,0,0,114,191,0,0,0,
+ 114,158,0,0,0,114,207,0,0,0,41,9,114,216,0,0,
+ 0,114,163,0,0,0,114,65,0,0,0,114,225,0,0,0,
+ 218,14,110,97,109,101,115,112,97,99,101,95,112,97,116,104,
+ 90,5,101,110,116,114,121,114,73,1,0,0,114,210,0,0,
+ 0,114,165,0,0,0,114,10,0,0,0,114,10,0,0,0,
+ 114,11,0,0,0,218,9,95,103,101,116,95,115,112,101,99,
+ 94,5,0,0,115,40,0,0,0,0,5,4,1,8,1,14,
+ 1,2,1,10,1,8,1,10,1,14,2,12,1,8,1,2,
+ 1,10,1,8,1,6,1,8,1,8,5,12,2,12,1,6,
+ 1,122,20,80,97,116,104,70,105,110,100,101,114,46,95,103,
+ 101,116,95,115,112,101,99,99,4,0,0,0,0,0,0,0,
+ 0,0,0,0,6,0,0,0,5,0,0,0,67,0,0,0,
+ 115,100,0,0,0,124,2,100,1,117,0,114,14,116,0,106,
+ 1,125,2,124,0,160,2,124,1,124,2,124,3,161,3,125,
+ 4,124,4,100,1,117,0,114,40,100,1,83,0,124,4,106,
+ 3,100,1,117,0,114,92,124,4,106,4,125,5,124,5,114,
+ 86,100,1,124,4,95,5,116,6,124,1,124,5,124,0,106,
+ 2,131,3,124,4,95,4,124,4,83,0,100,1,83,0,110,
+ 4,124,4,83,0,100,1,83,0,41,2,122,141,84,114,121,
+ 32,116,111,32,102,105,110,100,32,97,32,115,112,101,99,32,
+ 102,111,114,32,39,102,117,108,108,110,97,109,101,39,32,111,
+ 110,32,115,121,115,46,112,97,116,104,32,111,114,32,39,112,
+ 97,116,104,39,46,10,10,32,32,32,32,32,32,32,32,84,
+ 104,101,32,115,101,97,114,99,104,32,105,115,32,98,97,115,
+ 101,100,32,111,110,32,115,121,115,46,112,97,116,104,95,104,
+ 111,111,107,115,32,97,110,100,32,115,121,115,46,112,97,116,
+ 104,95,105,109,112,111,114,116,101,114,95,99,97,99,104,101,
+ 46,10,32,32,32,32,32,32,32,32,78,41,7,114,21,0,
+ 0,0,114,65,0,0,0,114,81,1,0,0,114,164,0,0,
+ 0,114,202,0,0,0,114,205,0,0,0,114,45,1,0,0,
+ 41,6,114,216,0,0,0,114,163,0,0,0,114,65,0,0,
+ 0,114,225,0,0,0,114,210,0,0,0,114,80,1,0,0,
+ 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,
+ 226,0,0,0,126,5,0,0,115,26,0,0,0,0,6,8,
+ 1,6,1,14,1,8,1,4,1,10,1,6,1,4,3,6,
+ 1,16,1,4,2,6,2,122,20,80,97,116,104,70,105,110,
+ 100,101,114,46,102,105,110,100,95,115,112,101,99,99,3,0,
+ 0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,
+ 0,0,67,0,0,0,115,30,0,0,0,124,0,160,0,124,
+ 1,124,2,161,2,125,3,124,3,100,1,117,0,114,24,100,
+ 1,83,0,124,3,106,1,83,0,41,2,122,170,102,105,110,
+ 100,32,116,104,101,32,109,111,100,117,108,101,32,111,110,32,
+ 115,121,115,46,112,97,116,104,32,111,114,32,39,112,97,116,
+ 104,39,32,98,97,115,101,100,32,111,110,32,115,121,115,46,
+ 112,97,116,104,95,104,111,111,107,115,32,97,110,100,10,32,
+ 32,32,32,32,32,32,32,115,121,115,46,112,97,116,104,95,
+ 105,109,112,111,114,116,101,114,95,99,97,99,104,101,46,10,
+ 10,32,32,32,32,32,32,32,32,84,104,105,115,32,109,101,
+ 116,104,111,100,32,105,115,32,100,101,112,114,101,99,97,116,
+ 101,100,46,32,32,85,115,101,32,102,105,110,100,95,115,112,
+ 101,99,40,41,32,105,110,115,116,101,97,100,46,10,10,32,
+ 32,32,32,32,32,32,32,78,114,227,0,0,0,114,228,0,
+ 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+ 0,114,229,0,0,0,150,5,0,0,115,8,0,0,0,0,
+ 8,12,1,8,1,4,1,122,22,80,97,116,104,70,105,110,
+ 100,101,114,46,102,105,110,100,95,109,111,100,117,108,101,99,
+ 1,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,
+ 4,0,0,0,79,0,0,0,115,28,0,0,0,100,1,100,
+ 2,108,0,109,1,125,3,1,0,124,3,106,2,124,1,105,
+ 0,124,2,164,1,142,1,83,0,41,3,97,32,1,0,0,
+ 10,32,32,32,32,32,32,32,32,70,105,110,100,32,100,105,
+ 115,116,114,105,98,117,116,105,111,110,115,46,10,10,32,32,
+ 32,32,32,32,32,32,82,101,116,117,114,110,32,97,110,32,
+ 105,116,101,114,97,98,108,101,32,111,102,32,97,108,108,32,
+ 68,105,115,116,114,105,98,117,116,105,111,110,32,105,110,115,
+ 116,97,110,99,101,115,32,99,97,112,97,98,108,101,32,111,
+ 102,10,32,32,32,32,32,32,32,32,108,111,97,100,105,110,
+ 103,32,116,104,101,32,109,101,116,97,100,97,116,97,32,102,
+ 111,114,32,112,97,99,107,97,103,101,115,32,109,97,116,99,
+ 104,105,110,103,32,96,96,99,111,110,116,101,120,116,46,110,
+ 97,109,101,96,96,10,32,32,32,32,32,32,32,32,40,111,
+ 114,32,97,108,108,32,110,97,109,101,115,32,105,102,32,96,
+ 96,78,111,110,101,96,96,32,105,110,100,105,99,97,116,101,
+ 100,41,32,97,108,111,110,103,32,116,104,101,32,112,97,116,
+ 104,115,32,105,110,32,116,104,101,32,108,105,115,116,10,32,
+ 32,32,32,32,32,32,32,111,102,32,100,105,114,101,99,116,
+ 111,114,105,101,115,32,96,96,99,111,110,116,101,120,116,46,
+ 112,97,116,104,96,96,46,10,32,32,32,32,32,32,32,32,
+ 114,0,0,0,0,41,1,218,18,77,101,116,97,100,97,116,
+ 97,80,97,116,104,70,105,110,100,101,114,41,3,90,18,105,
+ 109,112,111,114,116,108,105,98,46,109,101,116,97,100,97,116,
+ 97,114,82,1,0,0,218,18,102,105,110,100,95,100,105,115,
+ 116,114,105,98,117,116,105,111,110,115,41,4,114,216,0,0,
+ 0,114,143,0,0,0,114,144,0,0,0,114,82,1,0,0,
+ 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,
+ 83,1,0,0,163,5,0,0,115,4,0,0,0,0,10,12,
+ 1,122,29,80,97,116,104,70,105,110,100,101,114,46,102,105,
+ 110,100,95,100,105,115,116,114,105,98,117,116,105,111,110,115,
+ 41,1,78,41,2,78,78,41,1,78,41,13,114,149,0,0,
+ 0,114,148,0,0,0,114,150,0,0,0,114,151,0,0,0,
+ 114,230,0,0,0,114,69,1,0,0,114,75,1,0,0,114,
+ 77,1,0,0,114,78,1,0,0,114,81,1,0,0,114,226,
+ 0,0,0,114,229,0,0,0,114,83,1,0,0,114,10,0,
+ 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+ 0,114,68,1,0,0,30,5,0,0,115,34,0,0,0,8,
+ 2,4,2,2,1,10,9,2,1,10,12,2,1,10,21,2,
+ 1,10,14,2,1,12,31,2,1,12,23,2,1,12,12,2,
+ 1,114,68,1,0,0,99,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,3,0,0,0,64,0,0,0,115,
+ 90,0,0,0,101,0,90,1,100,0,90,2,100,1,90,3,
+ 100,2,100,3,132,0,90,4,100,4,100,5,132,0,90,5,
+ 101,6,90,7,100,6,100,7,132,0,90,8,100,8,100,9,
+ 132,0,90,9,100,19,100,11,100,12,132,1,90,10,100,13,
+ 100,14,132,0,90,11,101,12,100,15,100,16,132,0,131,1,
+ 90,13,100,17,100,18,132,0,90,14,100,10,83,0,41,20,
+ 218,10,70,105,108,101,70,105,110,100,101,114,122,172,70,105,
+ 108,101,45,98,97,115,101,100,32,102,105,110,100,101,114,46,
+ 10,10,32,32,32,32,73,110,116,101,114,97,99,116,105,111,
+ 110,115,32,119,105,116,104,32,116,104,101,32,102,105,108,101,
+ 32,115,121,115,116,101,109,32,97,114,101,32,99,97,99,104,
+ 101,100,32,102,111,114,32,112,101,114,102,111,114,109,97,110,
+ 99,101,44,32,98,101,105,110,103,10,32,32,32,32,114,101,
+ 102,114,101,115,104,101,100,32,119,104,101,110,32,116,104,101,
+ 32,100,105,114,101,99,116,111,114,121,32,116,104,101,32,102,
+ 105,110,100,101,114,32,105,115,32,104,97,110,100,108,105,110,
+ 103,32,104,97,115,32,98,101,101,110,32,109,111,100,105,102,
+ 105,101,100,46,10,10,32,32,32,32,99,2,0,0,0,0,
+ 0,0,0,0,0,0,0,5,0,0,0,6,0,0,0,7,
+ 0,0,0,115,112,0,0,0,103,0,125,3,124,2,68,0,
+ 93,32,92,2,137,0,125,4,124,3,160,0,135,0,102,1,
+ 100,1,100,2,132,8,124,4,68,0,131,1,161,1,1,0,
+ 113,8,124,3,124,0,95,1,124,1,112,54,100,3,124,0,
+ 95,2,116,3,124,0,106,2,131,1,115,86,116,4,116,5,
+ 160,6,161,0,124,0,106,2,131,2,124,0,95,2,100,4,
+ 124,0,95,7,116,8,131,0,124,0,95,9,116,8,131,0,
+ 124,0,95,10,100,5,83,0,41,6,122,154,73,110,105,116,
+ 105,97,108,105,122,101,32,119,105,116,104,32,116,104,101,32,
+ 112,97,116,104,32,116,111,32,115,101,97,114,99,104,32,111,
+ 110,32,97,110,100,32,97,32,118,97,114,105,97,98,108,101,
+ 32,110,117,109,98,101,114,32,111,102,10,32,32,32,32,32,
+ 32,32,32,50,45,116,117,112,108,101,115,32,99,111,110,116,
+ 97,105,110,105,110,103,32,116,104,101,32,108,111,97,100,101,
+ 114,32,97,110,100,32,116,104,101,32,102,105,108,101,32,115,
+ 117,102,102,105,120,101,115,32,116,104,101,32,108,111,97,100,
+ 101,114,10,32,32,32,32,32,32,32,32,114,101,99,111,103,
+ 110,105,122,101,115,46,99,1,0,0,0,0,0,0,0,0,
+ 0,0,0,2,0,0,0,3,0,0,0,51,0,0,0,115,
+ 22,0,0,0,124,0,93,14,125,1,124,1,136,0,102,2,
+ 86,0,1,0,113,2,100,0,83,0,114,69,0,0,0,114,
+ 10,0,0,0,114,40,1,0,0,169,1,114,164,0,0,0,
+ 114,10,0,0,0,114,11,0,0,0,114,12,0,0,0,192,
+ 5,0,0,114,13,0,0,0,122,38,70,105,108,101,70,105,
+ 110,100,101,114,46,95,95,105,110,105,116,95,95,46,60,108,
+ 111,99,97,108,115,62,46,60,103,101,110,101,120,112,114,62,
+ 114,96,0,0,0,114,129,0,0,0,78,41,11,114,191,0,
+ 0,0,218,8,95,108,111,97,100,101,114,115,114,65,0,0,
+ 0,114,85,0,0,0,114,67,0,0,0,114,24,0,0,0,
+ 114,81,0,0,0,218,11,95,112,97,116,104,95,109,116,105,
+ 109,101,218,3,115,101,116,218,11,95,112,97,116,104,95,99,
+ 97,99,104,101,218,19,95,114,101,108,97,120,101,100,95,112,
+ 97,116,104,95,99,97,99,104,101,41,5,114,142,0,0,0,
+ 114,65,0,0,0,218,14,108,111,97,100,101,114,95,100,101,
+ 116,97,105,108,115,90,7,108,111,97,100,101,114,115,114,212,
+ 0,0,0,114,10,0,0,0,114,85,1,0,0,114,11,0,
+ 0,0,114,232,0,0,0,186,5,0,0,115,20,0,0,0,
+ 0,4,4,1,12,1,26,1,6,2,10,1,10,1,18,1,
+ 6,1,8,1,122,19,70,105,108,101,70,105,110,100,101,114,
+ 46,95,95,105,110,105,116,95,95,99,1,0,0,0,0,0,
+ 0,0,0,0,0,0,1,0,0,0,2,0,0,0,67,0,
+ 0,0,115,10,0,0,0,100,1,124,0,95,0,100,2,83,
+ 0,41,3,122,31,73,110,118,97,108,105,100,97,116,101,32,
+ 116,104,101,32,100,105,114,101,99,116,111,114,121,32,109,116,
+ 105,109,101,46,114,129,0,0,0,78,41,1,114,87,1,0,
+ 0,114,13,1,0,0,114,10,0,0,0,114,10,0,0,0,
+ 114,11,0,0,0,114,69,1,0,0,202,5,0,0,115,2,
+ 0,0,0,0,2,122,28,70,105,108,101,70,105,110,100,101,
+ 114,46,105,110,118,97,108,105,100,97,116,101,95,99,97,99,
+ 104,101,115,99,2,0,0,0,0,0,0,0,0,0,0,0,
+ 3,0,0,0,3,0,0,0,67,0,0,0,115,42,0,0,
+ 0,124,0,160,0,124,1,161,1,125,2,124,2,100,1,117,
+ 0,114,26,100,1,103,0,102,2,83,0,124,2,106,1,124,
+ 2,106,2,112,38,103,0,102,2,83,0,41,2,122,197,84,
+ 114,121,32,116,111,32,102,105,110,100,32,97,32,108,111,97,
+ 100,101,114,32,102,111,114,32,116,104,101,32,115,112,101,99,
+ 105,102,105,101,100,32,109,111,100,117,108,101,44,32,111,114,
+ 32,116,104,101,32,110,97,109,101,115,112,97,99,101,10,32,
+ 32,32,32,32,32,32,32,112,97,99,107,97,103,101,32,112,
+ 111,114,116,105,111,110,115,46,32,82,101,116,117,114,110,115,
+ 32,40,108,111,97,100,101,114,44,32,108,105,115,116,45,111,
+ 102,45,112,111,114,116,105,111,110,115,41,46,10,10,32,32,
+ 32,32,32,32,32,32,84,104,105,115,32,109,101,116,104,111,
+ 100,32,105,115,32,100,101,112,114,101,99,97,116,101,100,46,
+ 32,32,85,115,101,32,102,105,110,100,95,115,112,101,99,40,
+ 41,32,105,110,115,116,101,97,100,46,10,10,32,32,32,32,
+ 32,32,32,32,78,41,3,114,226,0,0,0,114,164,0,0,
+ 0,114,202,0,0,0,41,3,114,142,0,0,0,114,163,0,
+ 0,0,114,210,0,0,0,114,10,0,0,0,114,10,0,0,
+ 0,114,11,0,0,0,114,161,0,0,0,208,5,0,0,115,
+ 8,0,0,0,0,7,10,1,8,1,8,1,122,22,70,105,
+ 108,101,70,105,110,100,101,114,46,102,105,110,100,95,108,111,
+ 97,100,101,114,99,6,0,0,0,0,0,0,0,0,0,0,
+ 0,7,0,0,0,6,0,0,0,67,0,0,0,115,26,0,
+ 0,0,124,1,124,2,124,3,131,2,125,6,116,0,124,2,
+ 124,3,124,6,124,4,100,1,141,4,83,0,41,2,78,114,
+ 201,0,0,0,41,1,114,213,0,0,0,41,7,114,142,0,
+ 0,0,114,211,0,0,0,114,163,0,0,0,114,65,0,0,
+ 0,90,4,115,109,115,108,114,225,0,0,0,114,164,0,0,
+ 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
+ 114,81,1,0,0,220,5,0,0,115,8,0,0,0,0,1,
+ 10,1,8,1,2,255,122,20,70,105,108,101,70,105,110,100,
+ 101,114,46,95,103,101,116,95,115,112,101,99,78,99,3,0,
+ 0,0,0,0,0,0,0,0,0,0,14,0,0,0,9,0,
+ 0,0,67,0,0,0,115,126,1,0,0,100,1,125,3,124,
+ 1,160,0,100,2,161,1,100,3,25,0,125,4,122,24,116,
+ 1,124,0,106,2,112,34,116,3,160,4,161,0,131,1,106,
+ 5,125,5,87,0,110,22,4,0,116,6,121,64,1,0,1,
+ 0,1,0,100,4,125,5,89,0,110,2,48,0,124,5,124,
+ 0,106,7,107,3,114,90,124,0,160,8,161,0,1,0,124,
+ 5,124,0,95,7,116,9,131,0,114,112,124,0,106,10,125,
+ 6,124,4,160,11,161,0,125,7,110,10,124,0,106,12,125,
+ 6,124,4,125,7,124,7,124,6,118,0,114,216,116,13,124,
+ 0,106,2,124,4,131,2,125,8,124,0,106,14,68,0,93,
+ 58,92,2,125,9,125,10,100,5,124,9,23,0,125,11,116,
+ 13,124,8,124,11,131,2,125,12,116,15,124,12,131,1,114,
+ 148,124,0,160,16,124,10,124,1,124,12,124,8,103,1,124,
+ 2,161,5,2,0,1,0,83,0,113,148,116,17,124,8,131,
+ 1,125,3,124,0,106,14,68,0,93,112,92,2,125,9,125,
+ 10,122,20,116,13,124,0,106,2,124,4,124,9,23,0,131,
+ 2,125,12,87,0,110,24,4,0,116,18,144,1,121,18,1,
+ 0,1,0,1,0,89,0,1,0,100,6,83,0,48,0,116,
+ 19,106,20,100,7,124,12,100,3,100,8,141,3,1,0,124,
+ 7,124,9,23,0,124,6,118,0,114,222,116,15,124,12,131,
+ 1,114,222,124,0,160,16,124,10,124,1,124,12,100,6,124,
+ 2,161,5,2,0,1,0,83,0,113,222,124,3,144,1,114,
+ 122,116,19,160,20,100,9,124,8,161,2,1,0,116,19,160,
+ 21,124,1,100,6,161,2,125,13,124,8,103,1,124,13,95,
+ 22,124,13,83,0,100,6,83,0,41,10,122,111,84,114,121,
+ 32,116,111,32,102,105,110,100,32,97,32,115,112,101,99,32,
+ 102,111,114,32,116,104,101,32,115,112,101,99,105,102,105,101,
+ 100,32,109,111,100,117,108,101,46,10,10,32,32,32,32,32,
+ 32,32,32,82,101,116,117,114,110,115,32,116,104,101,32,109,
+ 97,116,99,104,105,110,103,32,115,112,101,99,44,32,111,114,
+ 32,78,111,110,101,32,105,102,32,110,111,116,32,102,111,117,
+ 110,100,46,10,32,32,32,32,32,32,32,32,70,114,96,0,
+ 0,0,114,45,0,0,0,114,129,0,0,0,114,232,0,0,
+ 0,78,122,9,116,114,121,105,110,103,32,123,125,41,1,90,
+ 9,118,101,114,98,111,115,105,116,121,122,25,112,111,115,115,
+ 105,98,108,101,32,110,97,109,101,115,112,97,99,101,32,102,
+ 111,114,32,123,125,41,23,114,103,0,0,0,114,75,0,0,
+ 0,114,65,0,0,0,114,24,0,0,0,114,81,0,0,0,
+ 114,33,1,0,0,114,76,0,0,0,114,87,1,0,0,218,
+ 11,95,102,105,108,108,95,99,97,99,104,101,114,27,0,0,
+ 0,114,90,1,0,0,114,130,0,0,0,114,89,1,0,0,
+ 114,67,0,0,0,114,86,1,0,0,114,80,0,0,0,114,
+ 81,1,0,0,114,82,0,0,0,114,110,0,0,0,114,158,
+ 0,0,0,114,173,0,0,0,114,207,0,0,0,114,202,0,
+ 0,0,41,14,114,142,0,0,0,114,163,0,0,0,114,225,
+ 0,0,0,90,12,105,115,95,110,97,109,101,115,112,97,99,
+ 101,90,11,116,97,105,108,95,109,111,100,117,108,101,114,193,
+ 0,0,0,90,5,99,97,99,104,101,90,12,99,97,99,104,
+ 101,95,109,111,100,117,108,101,90,9,98,97,115,101,95,112,
+ 97,116,104,114,41,1,0,0,114,211,0,0,0,90,13,105,
+ 110,105,116,95,102,105,108,101,110,97,109,101,90,9,102,117,
+ 108,108,95,112,97,116,104,114,210,0,0,0,114,10,0,0,
+ 0,114,10,0,0,0,114,11,0,0,0,114,226,0,0,0,
+ 225,5,0,0,115,78,0,0,0,0,5,4,1,14,1,2,
+ 1,24,1,12,1,10,1,10,1,8,1,6,2,6,1,6,
+ 1,10,2,6,1,4,2,8,1,12,1,14,1,8,1,10,
+ 1,8,1,26,4,8,2,14,1,2,1,20,1,14,1,10,
+ 1,16,1,12,1,8,1,10,1,4,255,10,2,6,1,12,
+ 1,12,1,8,1,4,1,122,20,70,105,108,101,70,105,110,
+ 100,101,114,46,102,105,110,100,95,115,112,101,99,99,1,0,
+ 0,0,0,0,0,0,0,0,0,0,9,0,0,0,10,0,
+ 0,0,67,0,0,0,115,188,0,0,0,124,0,106,0,125,
+ 1,122,22,116,1,160,2,124,1,112,22,116,1,160,3,161,
+ 0,161,1,125,2,87,0,110,28,4,0,116,4,116,5,116,
+ 6,102,3,121,56,1,0,1,0,1,0,103,0,125,2,89,
+ 0,110,2,48,0,116,7,106,8,160,9,100,1,161,1,115,
+ 82,116,10,124,2,131,1,124,0,95,11,110,74,116,10,131,
+ 0,125,3,124,2,68,0,93,56,125,4,124,4,160,12,100,
+ 2,161,1,92,3,125,5,125,6,125,7,124,6,114,134,100,
+ 3,160,13,124,5,124,7,160,14,161,0,161,2,125,8,110,
+ 4,124,5,125,8,124,3,160,15,124,8,161,1,1,0,113,
+ 92,124,3,124,0,95,11,116,7,106,8,160,9,116,16,161,
+ 1,114,184,100,4,100,5,132,0,124,2,68,0,131,1,124,
+ 0,95,17,100,6,83,0,41,7,122,68,70,105,108,108,32,
+ 116,104,101,32,99,97,99,104,101,32,111,102,32,112,111,116,
+ 101,110,116,105,97,108,32,109,111,100,117,108,101,115,32,97,
+ 110,100,32,112,97,99,107,97,103,101,115,32,102,111,114,32,
+ 116,104,105,115,32,100,105,114,101,99,116,111,114,121,46,114,
+ 20,0,0,0,114,96,0,0,0,114,87,0,0,0,99,1,
+ 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,4,
+ 0,0,0,83,0,0,0,115,20,0,0,0,104,0,124,0,
+ 93,12,125,1,124,1,160,0,161,0,146,2,113,4,83,0,
+ 114,10,0,0,0,41,1,114,130,0,0,0,41,2,114,8,
+ 0,0,0,90,2,102,110,114,10,0,0,0,114,10,0,0,
+ 0,114,11,0,0,0,114,19,0,0,0,49,6,0,0,114,
+ 13,0,0,0,122,41,70,105,108,101,70,105,110,100,101,114,
+ 46,95,102,105,108,108,95,99,97,99,104,101,46,60,108,111,
+ 99,97,108,115,62,46,60,115,101,116,99,111,109,112,62,78,
+ 41,18,114,65,0,0,0,114,24,0,0,0,114,30,1,0,
+ 0,114,81,0,0,0,114,26,1,0,0,218,15,80,101,114,
+ 109,105,115,115,105,111,110,69,114,114,111,114,218,18,78,111,
+ 116,65,68,105,114,101,99,116,111,114,121,69,114,114,111,114,
+ 114,21,0,0,0,114,28,0,0,0,114,29,0,0,0,114,
+ 88,1,0,0,114,89,1,0,0,114,125,0,0,0,114,88,
+ 0,0,0,114,130,0,0,0,218,3,97,100,100,114,30,0,
+ 0,0,114,90,1,0,0,41,9,114,142,0,0,0,114,65,
+ 0,0,0,114,31,1,0,0,90,21,108,111,119,101,114,95,
+ 115,117,102,102,105,120,95,99,111,110,116,101,110,116,115,114,
+ 64,1,0,0,114,140,0,0,0,114,52,1,0,0,114,41,
+ 1,0,0,90,8,110,101,119,95,110,97,109,101,114,10,0,
+ 0,0,114,10,0,0,0,114,11,0,0,0,114,92,1,0,
+ 0,20,6,0,0,115,34,0,0,0,0,2,6,1,2,1,
+ 22,1,18,3,10,3,12,1,12,7,6,1,8,1,16,1,
+ 4,1,18,2,4,1,12,1,6,1,12,1,122,22,70,105,
+ 108,101,70,105,110,100,101,114,46,95,102,105,108,108,95,99,
+ 97,99,104,101,99,1,0,0,0,0,0,0,0,0,0,0,
+ 0,3,0,0,0,3,0,0,0,7,0,0,0,115,18,0,
+ 0,0,135,0,135,1,102,2,100,1,100,2,132,8,125,2,
+ 124,2,83,0,41,3,97,20,1,0,0,65,32,99,108,97,
+ 115,115,32,109,101,116,104,111,100,32,119,104,105,99,104,32,
+ 114,101,116,117,114,110,115,32,97,32,99,108,111,115,117,114,
+ 101,32,116,111,32,117,115,101,32,111,110,32,115,121,115,46,
+ 112,97,116,104,95,104,111,111,107,10,32,32,32,32,32,32,
+ 32,32,119,104,105,99,104,32,119,105,108,108,32,114,101,116,
+ 117,114,110,32,97,110,32,105,110,115,116,97,110,99,101,32,
+ 117,115,105,110,103,32,116,104,101,32,115,112,101,99,105,102,
+ 105,101,100,32,108,111,97,100,101,114,115,32,97,110,100,32,
+ 116,104,101,32,112,97,116,104,10,32,32,32,32,32,32,32,
+ 32,99,97,108,108,101,100,32,111,110,32,116,104,101,32,99,
+ 108,111,115,117,114,101,46,10,10,32,32,32,32,32,32,32,
+ 32,73,102,32,116,104,101,32,112,97,116,104,32,99,97,108,
+ 108,101,100,32,111,110,32,116,104,101,32,99,108,111,115,117,
+ 114,101,32,105,115,32,110,111,116,32,97,32,100,105,114,101,
+ 99,116,111,114,121,44,32,73,109,112,111,114,116,69,114,114,
+ 111,114,32,105,115,10,32,32,32,32,32,32,32,32,114,97,
+ 105,115,101,100,46,10,10,32,32,32,32,32,32,32,32,99,
+ 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,
+ 4,0,0,0,19,0,0,0,115,36,0,0,0,116,0,124,
+ 0,131,1,115,20,116,1,100,1,124,0,100,2,141,2,130,
+ 1,136,0,124,0,103,1,136,1,162,1,82,0,142,0,83,
+ 0,41,3,122,45,80,97,116,104,32,104,111,111,107,32,102,
+ 111,114,32,105,109,112,111,114,116,108,105,98,46,109,97,99,
+ 104,105,110,101,114,121,46,70,105,108,101,70,105,110,100,101,
+ 114,46,122,30,111,110,108,121,32,100,105,114,101,99,116,111,
+ 114,105,101,115,32,97,114,101,32,115,117,112,112,111,114,116,
+ 101,100,114,71,0,0,0,41,2,114,82,0,0,0,114,141,
+ 0,0,0,114,71,0,0,0,169,2,114,216,0,0,0,114,
+ 91,1,0,0,114,10,0,0,0,114,11,0,0,0,218,24,
+ 112,97,116,104,95,104,111,111,107,95,102,111,114,95,70,105,
+ 108,101,70,105,110,100,101,114,61,6,0,0,115,6,0,0,
+ 0,0,2,8,1,12,1,122,54,70,105,108,101,70,105,110,
+ 100,101,114,46,112,97,116,104,95,104,111,111,107,46,60,108,
+ 111,99,97,108,115,62,46,112,97,116,104,95,104,111,111,107,
+ 95,102,111,114,95,70,105,108,101,70,105,110,100,101,114,114,
+ 10,0,0,0,41,3,114,216,0,0,0,114,91,1,0,0,
+ 114,97,1,0,0,114,10,0,0,0,114,96,1,0,0,114,
+ 11,0,0,0,218,9,112,97,116,104,95,104,111,111,107,51,
+ 6,0,0,115,4,0,0,0,0,10,14,6,122,20,70,105,
+ 108,101,70,105,110,100,101,114,46,112,97,116,104,95,104,111,
+ 111,107,99,1,0,0,0,0,0,0,0,0,0,0,0,1,
+ 0,0,0,3,0,0,0,67,0,0,0,115,12,0,0,0,
+ 100,1,160,0,124,0,106,1,161,1,83,0,41,2,78,122,
+ 16,70,105,108,101,70,105,110,100,101,114,40,123,33,114,125,
+ 41,41,2,114,88,0,0,0,114,65,0,0,0,114,13,1,
+ 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+ 0,114,62,1,0,0,69,6,0,0,115,2,0,0,0,0,
+ 1,122,19,70,105,108,101,70,105,110,100,101,114,46,95,95,
+ 114,101,112,114,95,95,41,1,78,41,15,114,149,0,0,0,
+ 114,148,0,0,0,114,150,0,0,0,114,151,0,0,0,114,
+ 232,0,0,0,114,69,1,0,0,114,167,0,0,0,114,229,
+ 0,0,0,114,161,0,0,0,114,81,1,0,0,114,226,0,
+ 0,0,114,92,1,0,0,114,230,0,0,0,114,98,1,0,
+ 0,114,62,1,0,0,114,10,0,0,0,114,10,0,0,0,
+ 114,10,0,0,0,114,11,0,0,0,114,84,1,0,0,177,
+ 5,0,0,115,22,0,0,0,8,2,4,7,8,16,8,4,
+ 4,2,8,12,8,5,10,51,8,31,2,1,10,17,114,84,
+ 1,0,0,99,4,0,0,0,0,0,0,0,0,0,0,0,
+ 6,0,0,0,8,0,0,0,67,0,0,0,115,144,0,0,
+ 0,124,0,160,0,100,1,161,1,125,4,124,0,160,0,100,
+ 2,161,1,125,5,124,4,115,66,124,5,114,36,124,5,106,
+ 1,125,4,110,30,124,2,124,3,107,2,114,56,116,2,124,
+ 1,124,2,131,2,125,4,110,10,116,3,124,1,124,2,131,
+ 2,125,4,124,5,115,84,116,4,124,1,124,2,124,4,100,
+ 3,141,3,125,5,122,36,124,5,124,0,100,2,60,0,124,
+ 4,124,0,100,1,60,0,124,2,124,0,100,4,60,0,124,
+ 3,124,0,100,5,60,0,87,0,110,18,4,0,116,5,121,
+ 138,1,0,1,0,1,0,89,0,110,2,48,0,100,0,83,
+ 0,41,6,78,218,10,95,95,108,111,97,100,101,114,95,95,
+ 218,8,95,95,115,112,101,99,95,95,114,85,1,0,0,90,
+ 8,95,95,102,105,108,101,95,95,90,10,95,95,99,97,99,
+ 104,101,100,95,95,41,6,218,3,103,101,116,114,164,0,0,
+ 0,114,39,1,0,0,114,32,1,0,0,114,213,0,0,0,
+ 218,9,69,120,99,101,112,116,105,111,110,41,6,90,2,110,
+ 115,114,140,0,0,0,90,8,112,97,116,104,110,97,109,101,
+ 90,9,99,112,97,116,104,110,97,109,101,114,164,0,0,0,
+ 114,210,0,0,0,114,10,0,0,0,114,10,0,0,0,114,
+ 11,0,0,0,218,14,95,102,105,120,95,117,112,95,109,111,
+ 100,117,108,101,75,6,0,0,115,34,0,0,0,0,2,10,
+ 1,10,1,4,1,4,1,8,1,8,1,12,2,10,1,4,
+ 1,14,1,2,1,8,1,8,1,8,1,12,1,12,2,114,
+ 103,1,0,0,99,0,0,0,0,0,0,0,0,0,0,0,
+ 0,3,0,0,0,3,0,0,0,67,0,0,0,115,38,0,
+ 0,0,116,0,116,1,160,2,161,0,102,2,125,0,116,3,
+ 116,4,102,2,125,1,116,5,116,6,102,2,125,2,124,0,
+ 124,1,124,2,103,3,83,0,41,1,122,95,82,101,116,117,
+ 114,110,115,32,97,32,108,105,115,116,32,111,102,32,102,105,
+ 108,101,45,98,97,115,101,100,32,109,111,100,117,108,101,32,
+ 108,111,97,100,101,114,115,46,10,10,32,32,32,32,69,97,
+ 99,104,32,105,116,101,109,32,105,115,32,97,32,116,117,112,
+ 108,101,32,40,108,111,97,100,101,114,44,32,115,117,102,102,
+ 105,120,101,115,41,46,10,32,32,32,32,41,7,114,19,1,
+ 0,0,114,187,0,0,0,218,18,101,120,116,101,110,115,105,
+ 111,110,95,115,117,102,102,105,120,101,115,114,32,1,0,0,
+ 114,126,0,0,0,114,39,1,0,0,114,112,0,0,0,41,
+ 3,90,10,101,120,116,101,110,115,105,111,110,115,90,6,115,
+ 111,117,114,99,101,90,8,98,121,116,101,99,111,100,101,114,
+ 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,208,
+ 0,0,0,98,6,0,0,115,8,0,0,0,0,5,12,1,
+ 8,1,8,1,114,208,0,0,0,99,1,0,0,0,0,0,
+ 0,0,0,0,0,0,10,0,0,0,9,0,0,0,67,0,
+ 0,0,115,132,1,0,0,124,0,97,0,116,0,106,1,97,
+ 1,116,0,106,2,97,2,116,1,106,3,116,4,25,0,125,
+ 1,100,1,100,2,103,1,102,2,100,3,100,4,100,2,103,
+ 2,102,2,102,2,125,2,124,2,68,0,93,108,92,2,125,
+ 3,125,4,116,5,100,5,100,6,132,0,124,4,68,0,131,
+ 1,131,1,115,82,74,0,130,1,124,4,100,7,25,0,125,
+ 5,124,3,116,1,106,3,118,0,114,116,116,1,106,3,124,
+ 3,25,0,125,6,1,0,113,170,113,52,122,20,116,0,160,
+ 6,124,3,161,1,125,6,87,0,1,0,113,170,87,0,113,
+ 52,4,0,116,7,121,158,1,0,1,0,1,0,89,0,113,
+ 52,89,0,113,52,48,0,113,52,116,7,100,8,131,1,130,
+ 1,116,8,124,1,100,9,124,6,131,3,1,0,116,8,124,
+ 1,100,10,124,5,131,3,1,0,116,8,124,1,100,11,100,
+ 12,160,9,124,4,161,1,131,3,1,0,116,8,124,1,100,
+ 13,100,14,100,15,132,0,124,4,68,0,131,1,131,3,1,
+ 0,103,0,100,16,162,1,125,7,124,3,100,3,107,2,144,
+ 1,114,6,124,7,160,10,100,17,161,1,1,0,124,7,68,
+ 0,93,52,125,8,124,8,116,1,106,3,118,1,144,1,114,
+ 38,116,0,160,6,124,8,161,1,125,9,110,10,116,1,106,
+ 3,124,8,25,0,125,9,116,8,124,1,124,8,124,9,131,
+ 3,1,0,144,1,113,10,116,8,124,1,100,18,116,11,131,
+ 0,131,3,1,0,116,12,160,13,116,2,160,14,161,0,161,
+ 1,1,0,124,3,100,3,107,2,144,1,114,128,116,15,160,
+ 10,100,19,161,1,1,0,100,20,116,12,118,0,144,1,114,
+ 128,100,21,116,16,95,17,100,22,83,0,41,23,122,205,83,
+ 101,116,117,112,32,116,104,101,32,112,97,116,104,45,98,97,
+ 115,101,100,32,105,109,112,111,114,116,101,114,115,32,102,111,
+ 114,32,105,109,112,111,114,116,108,105,98,32,98,121,32,105,
+ 109,112,111,114,116,105,110,103,32,110,101,101,100,101,100,10,
+ 32,32,32,32,98,117,105,108,116,45,105,110,32,109,111,100,
+ 117,108,101,115,32,97,110,100,32,105,110,106,101,99,116,105,
+ 110,103,32,116,104,101,109,32,105,110,116,111,32,116,104,101,
+ 32,103,108,111,98,97,108,32,110,97,109,101,115,112,97,99,
+ 101,46,10,10,32,32,32,32,79,116,104,101,114,32,99,111,
+ 109,112,111,110,101,110,116,115,32,97,114,101,32,101,120,116,
+ 114,97,99,116,101,100,32,102,114,111,109,32,116,104,101,32,
+ 99,111,114,101,32,98,111,111,116,115,116,114,97,112,32,109,
+ 111,100,117,108,101,46,10,10,32,32,32,32,218,5,112,111,
+ 115,105,120,114,2,0,0,0,218,2,110,116,114,1,0,0,
+ 0,99,1,0,0,0,0,0,0,0,0,0,0,0,2,0,
+ 0,0,3,0,0,0,115,0,0,0,115,26,0,0,0,124,
+ 0,93,18,125,1,116,0,124,1,131,1,100,0,107,2,86,
+ 0,1,0,113,2,100,1,83,0,114,3,0,0,0,114,5,
+ 0,0,0,114,7,0,0,0,114,10,0,0,0,114,10,0,
+ 0,0,114,11,0,0,0,114,12,0,0,0,127,6,0,0,
+ 114,13,0,0,0,122,25,95,115,101,116,117,112,46,60,108,
+ 111,99,97,108,115,62,46,60,103,101,110,101,120,112,114,62,
+ 114,0,0,0,0,122,30,105,109,112,111,114,116,108,105,98,
+ 32,114,101,113,117,105,114,101,115,32,112,111,115,105,120,32,
+ 111,114,32,110,116,114,24,0,0,0,114,59,0,0,0,114,
+ 50,0,0,0,114,14,0,0,0,218,20,95,112,97,116,104,
+ 115,101,112,115,95,119,105,116,104,95,99,111,108,111,110,99,
+ 1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,
+ 4,0,0,0,83,0,0,0,115,22,0,0,0,104,0,124,
+ 0,93,14,125,1,100,0,124,1,155,0,157,2,146,2,113,
+ 4,83,0,114,15,0,0,0,114,10,0,0,0,114,17,0,
+ 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+ 0,114,19,0,0,0,144,6,0,0,114,13,0,0,0,122,
+ 25,95,115,101,116,117,112,46,60,108,111,99,97,108,115,62,
+ 46,60,115,101,116,99,111,109,112,62,41,3,114,90,0,0,
+ 0,114,98,0,0,0,114,184,0,0,0,114,215,0,0,0,
+ 114,27,0,0,0,122,4,46,112,121,119,122,6,95,100,46,
+ 112,121,100,84,78,41,18,114,158,0,0,0,114,21,0,0,
+ 0,114,187,0,0,0,114,54,1,0,0,114,149,0,0,0,
+ 218,3,97,108,108,90,18,95,98,117,105,108,116,105,110,95,
+ 102,114,111,109,95,110,97,109,101,114,141,0,0,0,114,153,
+ 0,0,0,114,62,0,0,0,114,61,0,0,0,114,32,0,
+ 0,0,114,44,1,0,0,114,191,0,0,0,114,104,1,0,
+ 0,114,126,0,0,0,114,214,0,0,0,114,218,0,0,0,
+ 41,10,218,17,95,98,111,111,116,115,116,114,97,112,95,109,
+ 111,100,117,108,101,90,11,115,101,108,102,95,109,111,100,117,
+ 108,101,90,10,111,115,95,100,101,116,97,105,108,115,90,10,
+ 98,117,105,108,116,105,110,95,111,115,114,50,0,0,0,114,
+ 59,0,0,0,90,9,111,115,95,109,111,100,117,108,101,90,
+ 13,98,117,105,108,116,105,110,95,110,97,109,101,115,90,12,
+ 98,117,105,108,116,105,110,95,110,97,109,101,90,14,98,117,
+ 105,108,116,105,110,95,109,111,100,117,108,101,114,10,0,0,
+ 0,114,10,0,0,0,114,11,0,0,0,218,6,95,115,101,
+ 116,117,112,109,6,0,0,115,70,0,0,0,0,8,4,1,
+ 6,1,6,2,10,3,22,1,12,2,22,1,8,1,10,1,
+ 10,1,6,2,2,1,10,1,10,1,12,1,12,2,8,2,
+ 12,1,12,1,18,1,22,3,8,1,10,1,10,1,8,1,
+ 12,1,12,2,10,1,16,3,14,1,14,1,10,1,10,1,
+ 10,1,114,110,1,0,0,99,1,0,0,0,0,0,0,0,
+ 0,0,0,0,2,0,0,0,4,0,0,0,67,0,0,0,
+ 115,50,0,0,0,116,0,124,0,131,1,1,0,116,1,131,
+ 0,125,1,116,2,106,3,160,4,116,5,106,6,124,1,142,
+ 0,103,1,161,1,1,0,116,2,106,7,160,8,116,9,161,
+ 1,1,0,100,1,83,0,41,2,122,41,73,110,115,116,97,
+ 108,108,32,116,104,101,32,112,97,116,104,45,98,97,115,101,
+ 100,32,105,109,112,111,114,116,32,99,111,109,112,111,110,101,
+ 110,116,115,46,78,41,10,114,110,1,0,0,114,208,0,0,
+ 0,114,21,0,0,0,114,74,1,0,0,114,191,0,0,0,
+ 114,84,1,0,0,114,98,1,0,0,218,9,109,101,116,97,
+ 95,112,97,116,104,114,61,0,0,0,114,68,1,0,0,41,
+ 2,114,109,1,0,0,90,17,115,117,112,112,111,114,116,101,
+ 100,95,108,111,97,100,101,114,115,114,10,0,0,0,114,10,
+ 0,0,0,114,11,0,0,0,218,8,95,105,110,115,116,97,
+ 108,108,166,6,0,0,115,8,0,0,0,0,2,8,1,6,
+ 1,20,1,114,112,1,0,0,41,1,114,86,0,0,0,41,
+ 1,78,41,3,78,78,78,41,2,114,0,0,0,0,114,0,
+ 0,0,0,41,1,84,41,1,78,41,1,78,41,81,114,151,
+ 0,0,0,114,187,0,0,0,114,90,0,0,0,114,21,0,
+ 0,0,114,98,0,0,0,114,184,0,0,0,114,28,0,0,
+ 0,90,11,95,77,83,95,87,73,78,68,79,87,83,114,106,
+ 1,0,0,114,24,0,0,0,114,215,0,0,0,114,105,1,
+ 0,0,114,50,0,0,0,114,108,1,0,0,114,59,0,0,
+ 0,114,135,0,0,0,114,57,0,0,0,114,62,0,0,0,
+ 114,107,1,0,0,114,31,0,0,0,90,37,95,67,65,83,
+ 69,95,73,78,83,69,78,83,73,84,73,86,69,95,80,76,
+ 65,84,70,79,82,77,83,95,66,89,84,69,83,95,75,69,
+ 89,114,30,0,0,0,114,32,0,0,0,114,39,0,0,0,
+ 114,44,0,0,0,114,46,0,0,0,114,67,0,0,0,114,
+ 74,0,0,0,114,75,0,0,0,114,79,0,0,0,114,80,
+ 0,0,0,114,82,0,0,0,114,85,0,0,0,114,94,0,
+ 0,0,218,4,116,121,112,101,218,8,95,95,99,111,100,101,
+ 95,95,114,186,0,0,0,114,37,0,0,0,114,172,0,0,
+ 0,114,36,0,0,0,114,41,0,0,0,114,3,1,0,0,
+ 114,115,0,0,0,114,111,0,0,0,114,126,0,0,0,114,
+ 112,0,0,0,90,23,68,69,66,85,71,95,66,89,84,69,
+ 67,79,68,69,95,83,85,70,70,73,88,69,83,90,27,79,
+ 80,84,73,77,73,90,69,68,95,66,89,84,69,67,79,68,
+ 69,95,83,85,70,70,73,88,69,83,114,120,0,0,0,114,
+ 127,0,0,0,114,134,0,0,0,114,136,0,0,0,114,138,
+ 0,0,0,114,160,0,0,0,114,167,0,0,0,114,176,0,
+ 0,0,114,180,0,0,0,114,182,0,0,0,114,189,0,0,
+ 0,114,194,0,0,0,114,195,0,0,0,114,200,0,0,0,
+ 218,6,111,98,106,101,99,116,114,209,0,0,0,114,213,0,
+ 0,0,114,214,0,0,0,114,231,0,0,0,114,244,0,0,
+ 0,114,6,1,0,0,114,32,1,0,0,114,39,1,0,0,
+ 114,44,1,0,0,114,19,1,0,0,114,45,1,0,0,114,
+ 66,1,0,0,114,68,1,0,0,114,84,1,0,0,114,103,
+ 1,0,0,114,208,0,0,0,114,110,1,0,0,114,112,1,
+ 0,0,114,10,0,0,0,114,10,0,0,0,114,10,0,0,
+ 0,114,11,0,0,0,218,8,60,109,111,100,117,108,101,62,
+ 1,0,0,0,115,170,0,0,0,4,22,8,1,8,1,8,
+ 1,8,1,8,3,10,1,4,1,8,1,10,2,8,3,4,
+ 1,10,2,6,2,22,1,8,1,8,1,10,1,14,4,4,
+ 1,4,1,2,1,2,255,4,4,8,17,8,5,8,5,8,
+ 6,4,1,10,30,8,6,8,8,8,10,8,9,8,5,8,
+ 7,6,1,10,8,8,5,10,22,10,127,0,20,16,1,12,
+ 2,4,1,4,2,6,2,6,2,8,2,16,71,8,40,8,
+ 19,8,12,8,12,8,28,8,17,8,33,8,28,8,24,10,
+ 13,10,10,10,11,8,14,6,3,4,1,2,255,12,68,14,
+ 64,14,29,16,127,0,17,14,72,18,45,18,26,4,3,18,
+ 58,14,63,14,42,14,127,0,20,14,127,0,27,10,23,8,
+ 11,8,57,
+};
diff --git a/contrib/tools/python3/src/Python/importlib_zipimport.h b/contrib/tools/python3/src/Python/importlib_zipimport.h
new file mode 100644
index 00000000000..373b1366bde
--- /dev/null
+++ b/contrib/tools/python3/src/Python/importlib_zipimport.h
@@ -0,0 +1,1079 @@
+/* Auto-generated by Programs/_freeze_importlib.c */
+const unsigned char _Py_M__zipimport[] = {
+ 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,4,0,0,0,64,0,0,0,115,82,1,0,0,100,0,
+ 90,0,100,1,100,2,108,1,90,2,100,1,100,3,108,1,
+ 109,3,90,3,109,4,90,4,1,0,100,1,100,2,108,5,
+ 90,6,100,1,100,2,108,7,90,7,100,1,100,2,108,8,
+ 90,8,100,1,100,2,108,9,90,9,100,1,100,2,108,10,
+ 90,10,100,1,100,2,108,11,90,11,100,4,100,5,103,2,
+ 90,12,101,2,106,13,90,13,101,2,106,14,100,6,100,2,
+ 133,2,25,0,90,15,71,0,100,7,100,4,132,0,100,4,
+ 101,16,131,3,90,17,105,0,90,18,101,19,101,10,131,1,
+ 90,20,100,8,90,21,100,9,90,22,100,10,90,23,71,0,
+ 100,11,100,5,132,0,100,5,131,2,90,24,101,13,100,12,
+ 23,0,100,13,100,13,102,3,101,13,100,14,23,0,100,15,
+ 100,13,102,3,100,16,100,17,102,4,90,25,100,18,100,19,
+ 132,0,90,26,100,20,100,21,132,0,90,27,100,22,100,23,
+ 132,0,90,28,100,24,100,25,132,0,90,29,100,26,90,30,
+ 100,15,97,31,100,27,100,28,132,0,90,32,100,29,100,30,
+ 132,0,90,33,100,31,100,32,132,0,90,34,100,33,100,34,
+ 132,0,90,35,101,19,101,35,106,36,131,1,90,37,100,35,
+ 100,36,132,0,90,38,100,37,100,38,132,0,90,39,100,39,
+ 100,40,132,0,90,40,100,41,100,42,132,0,90,41,100,43,
+ 100,44,132,0,90,42,100,45,100,46,132,0,90,43,71,0,
+ 100,47,100,48,132,0,100,48,131,2,90,44,100,2,83,0,
+ 41,49,97,80,2,0,0,122,105,112,105,109,112,111,114,116,
+ 32,112,114,111,118,105,100,101,115,32,115,117,112,112,111,114,
+ 116,32,102,111,114,32,105,109,112,111,114,116,105,110,103,32,
+ 80,121,116,104,111,110,32,109,111,100,117,108,101,115,32,102,
+ 114,111,109,32,90,105,112,32,97,114,99,104,105,118,101,115,
+ 46,10,10,84,104,105,115,32,109,111,100,117,108,101,32,101,
+ 120,112,111,114,116,115,32,116,104,114,101,101,32,111,98,106,
+ 101,99,116,115,58,10,45,32,122,105,112,105,109,112,111,114,
+ 116,101,114,58,32,97,32,99,108,97,115,115,59,32,105,116,
+ 115,32,99,111,110,115,116,114,117,99,116,111,114,32,116,97,
+ 107,101,115,32,97,32,112,97,116,104,32,116,111,32,97,32,
+ 90,105,112,32,97,114,99,104,105,118,101,46,10,45,32,90,
+ 105,112,73,109,112,111,114,116,69,114,114,111,114,58,32,101,
+ 120,99,101,112,116,105,111,110,32,114,97,105,115,101,100,32,
+ 98,121,32,122,105,112,105,109,112,111,114,116,101,114,32,111,
+ 98,106,101,99,116,115,46,32,73,116,39,115,32,97,10,32,
+ 32,115,117,98,99,108,97,115,115,32,111,102,32,73,109,112,
+ 111,114,116,69,114,114,111,114,44,32,115,111,32,105,116,32,
+ 99,97,110,32,98,101,32,99,97,117,103,104,116,32,97,115,
+ 32,73,109,112,111,114,116,69,114,114,111,114,44,32,116,111,
+ 111,46,10,45,32,95,122,105,112,95,100,105,114,101,99,116,
+ 111,114,121,95,99,97,99,104,101,58,32,97,32,100,105,99,
+ 116,44,32,109,97,112,112,105,110,103,32,97,114,99,104,105,
+ 118,101,32,112,97,116,104,115,32,116,111,32,122,105,112,32,
+ 100,105,114,101,99,116,111,114,121,10,32,32,105,110,102,111,
+ 32,100,105,99,116,115,44,32,97,115,32,117,115,101,100,32,
+ 105,110,32,122,105,112,105,109,112,111,114,116,101,114,46,95,
+ 102,105,108,101,115,46,10,10,73,116,32,105,115,32,117,115,
+ 117,97,108,108,121,32,110,111,116,32,110,101,101,100,101,100,
+ 32,116,111,32,117,115,101,32,116,104,101,32,122,105,112,105,
+ 109,112,111,114,116,32,109,111,100,117,108,101,32,101,120,112,
+ 108,105,99,105,116,108,121,59,32,105,116,32,105,115,10,117,
+ 115,101,100,32,98,121,32,116,104,101,32,98,117,105,108,116,
+ 105,110,32,105,109,112,111,114,116,32,109,101,99,104,97,110,
+ 105,115,109,32,102,111,114,32,115,121,115,46,112,97,116,104,
+ 32,105,116,101,109,115,32,116,104,97,116,32,97,114,101,32,
+ 112,97,116,104,115,10,116,111,32,90,105,112,32,97,114,99,
+ 104,105,118,101,115,46,10,233,0,0,0,0,78,41,2,218,
+ 14,95,117,110,112,97,99,107,95,117,105,110,116,49,54,218,
+ 14,95,117,110,112,97,99,107,95,117,105,110,116,51,50,218,
+ 14,90,105,112,73,109,112,111,114,116,69,114,114,111,114,218,
+ 11,122,105,112,105,109,112,111,114,116,101,114,233,1,0,0,
+ 0,99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,1,0,0,0,64,0,0,0,115,12,0,0,0,101,
+ 0,90,1,100,0,90,2,100,1,83,0,41,2,114,3,0,
+ 0,0,78,41,3,218,8,95,95,110,97,109,101,95,95,218,
+ 10,95,95,109,111,100,117,108,101,95,95,218,12,95,95,113,
+ 117,97,108,110,97,109,101,95,95,169,0,114,9,0,0,0,
+ 114,9,0,0,0,250,18,60,102,114,111,122,101,110,32,122,
+ 105,112,105,109,112,111,114,116,62,114,3,0,0,0,33,0,
+ 0,0,115,2,0,0,0,8,1,233,22,0,0,0,115,4,
+ 0,0,0,80,75,5,6,105,255,255,0,0,99,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,
+ 0,64,0,0,0,115,108,0,0,0,101,0,90,1,100,0,
+ 90,2,100,1,90,3,100,2,100,3,132,0,90,4,100,25,
+ 100,5,100,6,132,1,90,5,100,26,100,7,100,8,132,1,
+ 90,6,100,9,100,10,132,0,90,7,100,11,100,12,132,0,
+ 90,8,100,13,100,14,132,0,90,9,100,15,100,16,132,0,
+ 90,10,100,17,100,18,132,0,90,11,100,19,100,20,132,0,
+ 90,12,100,21,100,22,132,0,90,13,100,23,100,24,132,0,
+ 90,14,100,4,83,0,41,27,114,4,0,0,0,97,255,1,
+ 0,0,122,105,112,105,109,112,111,114,116,101,114,40,97,114,
+ 99,104,105,118,101,112,97,116,104,41,32,45,62,32,122,105,
+ 112,105,109,112,111,114,116,101,114,32,111,98,106,101,99,116,
+ 10,10,32,32,32,32,67,114,101,97,116,101,32,97,32,110,
+ 101,119,32,122,105,112,105,109,112,111,114,116,101,114,32,105,
+ 110,115,116,97,110,99,101,46,32,39,97,114,99,104,105,118,
+ 101,112,97,116,104,39,32,109,117,115,116,32,98,101,32,97,
+ 32,112,97,116,104,32,116,111,10,32,32,32,32,97,32,122,
+ 105,112,102,105,108,101,44,32,111,114,32,116,111,32,97,32,
+ 115,112,101,99,105,102,105,99,32,112,97,116,104,32,105,110,
+ 115,105,100,101,32,97,32,122,105,112,102,105,108,101,46,32,
+ 70,111,114,32,101,120,97,109,112,108,101,44,32,105,116,32,
+ 99,97,110,32,98,101,10,32,32,32,32,39,47,116,109,112,
+ 47,109,121,105,109,112,111,114,116,46,122,105,112,39,44,32,
+ 111,114,32,39,47,116,109,112,47,109,121,105,109,112,111,114,
+ 116,46,122,105,112,47,109,121,100,105,114,101,99,116,111,114,
+ 121,39,44,32,105,102,32,109,121,100,105,114,101,99,116,111,
+ 114,121,32,105,115,32,97,10,32,32,32,32,118,97,108,105,
+ 100,32,100,105,114,101,99,116,111,114,121,32,105,110,115,105,
+ 100,101,32,116,104,101,32,97,114,99,104,105,118,101,46,10,
+ 10,32,32,32,32,39,90,105,112,73,109,112,111,114,116,69,
+ 114,114,111,114,32,105,115,32,114,97,105,115,101,100,32,105,
+ 102,32,39,97,114,99,104,105,118,101,112,97,116,104,39,32,
+ 100,111,101,115,110,39,116,32,112,111,105,110,116,32,116,111,
+ 32,97,32,118,97,108,105,100,32,90,105,112,10,32,32,32,
+ 32,97,114,99,104,105,118,101,46,10,10,32,32,32,32,84,
+ 104,101,32,39,97,114,99,104,105,118,101,39,32,97,116,116,
+ 114,105,98,117,116,101,32,111,102,32,122,105,112,105,109,112,
+ 111,114,116,101,114,32,111,98,106,101,99,116,115,32,99,111,
+ 110,116,97,105,110,115,32,116,104,101,32,110,97,109,101,32,
+ 111,102,32,116,104,101,10,32,32,32,32,122,105,112,102,105,
+ 108,101,32,116,97,114,103,101,116,101,100,46,10,32,32,32,
+ 32,99,2,0,0,0,0,0,0,0,0,0,0,0,8,0,
+ 0,0,9,0,0,0,67,0,0,0,115,32,1,0,0,116,
+ 0,124,1,116,1,131,2,115,28,100,1,100,0,108,2,125,
+ 2,124,2,160,3,124,1,161,1,125,1,124,1,115,44,116,
+ 4,100,2,124,1,100,3,141,2,130,1,116,5,114,60,124,
+ 1,160,6,116,5,116,7,161,2,125,1,103,0,125,3,122,
+ 14,116,8,160,9,124,1,161,1,125,4,87,0,110,70,4,
+ 0,116,10,116,11,102,2,121,148,1,0,1,0,1,0,116,
+ 8,160,12,124,1,161,1,92,2,125,5,125,6,124,5,124,
+ 1,107,2,114,130,116,4,100,4,124,1,100,3,141,2,130,
+ 1,124,5,125,1,124,3,160,13,124,6,161,1,1,0,89,
+ 0,113,64,48,0,124,4,106,14,100,5,64,0,100,6,107,
+ 3,114,180,116,4,100,4,124,1,100,3,141,2,130,1,113,
+ 180,113,64,122,12,116,15,124,1,25,0,125,7,87,0,110,
+ 34,4,0,116,16,121,226,1,0,1,0,1,0,116,17,124,
+ 1,131,1,125,7,124,7,116,15,124,1,60,0,89,0,110,
+ 2,48,0,124,7,124,0,95,18,124,1,124,0,95,19,116,
+ 8,106,20,124,3,100,0,100,0,100,7,133,3,25,0,142,
+ 0,124,0,95,21,124,0,106,21,144,1,114,28,124,0,4,
+ 0,106,21,116,7,55,0,2,0,95,21,100,0,83,0,41,
+ 8,78,114,0,0,0,0,122,21,97,114,99,104,105,118,101,
+ 32,112,97,116,104,32,105,115,32,101,109,112,116,121,169,1,
+ 218,4,112,97,116,104,122,14,110,111,116,32,97,32,90,105,
+ 112,32,102,105,108,101,105,0,240,0,0,105,0,128,0,0,
+ 233,255,255,255,255,41,22,218,10,105,115,105,110,115,116,97,
+ 110,99,101,218,3,115,116,114,218,2,111,115,90,8,102,115,
+ 100,101,99,111,100,101,114,3,0,0,0,218,12,97,108,116,
+ 95,112,97,116,104,95,115,101,112,218,7,114,101,112,108,97,
+ 99,101,218,8,112,97,116,104,95,115,101,112,218,19,95,98,
+ 111,111,116,115,116,114,97,112,95,101,120,116,101,114,110,97,
+ 108,90,10,95,112,97,116,104,95,115,116,97,116,218,7,79,
+ 83,69,114,114,111,114,218,10,86,97,108,117,101,69,114,114,
+ 111,114,90,11,95,112,97,116,104,95,115,112,108,105,116,218,
+ 6,97,112,112,101,110,100,90,7,115,116,95,109,111,100,101,
+ 218,20,95,122,105,112,95,100,105,114,101,99,116,111,114,121,
+ 95,99,97,99,104,101,218,8,75,101,121,69,114,114,111,114,
+ 218,15,95,114,101,97,100,95,100,105,114,101,99,116,111,114,
+ 121,218,6,95,102,105,108,101,115,218,7,97,114,99,104,105,
+ 118,101,218,10,95,112,97,116,104,95,106,111,105,110,218,6,
+ 112,114,101,102,105,120,41,8,218,4,115,101,108,102,114,13,
+ 0,0,0,114,17,0,0,0,114,31,0,0,0,90,2,115,
+ 116,90,7,100,105,114,110,97,109,101,90,8,98,97,115,101,
+ 110,97,109,101,218,5,102,105,108,101,115,114,9,0,0,0,
+ 114,9,0,0,0,114,10,0,0,0,218,8,95,95,105,110,
+ 105,116,95,95,63,0,0,0,115,58,0,0,0,0,1,10,
+ 1,8,1,10,1,4,1,12,1,4,1,12,2,4,2,2,
+ 1,14,1,16,3,14,1,8,1,12,1,4,1,16,3,14,
+ 2,12,1,4,2,2,1,12,1,12,1,8,1,14,1,6,
+ 1,6,2,22,1,8,1,122,20,122,105,112,105,109,112,111,
+ 114,116,101,114,46,95,95,105,110,105,116,95,95,78,99,3,
+ 0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,
+ 0,0,0,67,0,0,0,115,78,0,0,0,116,0,124,0,
+ 124,1,131,2,125,3,124,3,100,1,117,1,114,26,124,0,
+ 103,0,102,2,83,0,116,1,124,0,124,1,131,2,125,4,
+ 116,2,124,0,124,4,131,2,114,70,100,1,124,0,106,3,
+ 155,0,116,4,155,0,124,4,155,0,157,3,103,1,102,2,
+ 83,0,100,1,103,0,102,2,83,0,41,2,97,239,1,0,
+ 0,102,105,110,100,95,108,111,97,100,101,114,40,102,117,108,
+ 108,110,97,109,101,44,32,112,97,116,104,61,78,111,110,101,
+ 41,32,45,62,32,115,101,108,102,44,32,115,116,114,32,111,
+ 114,32,78,111,110,101,46,10,10,32,32,32,32,32,32,32,
+ 32,83,101,97,114,99,104,32,102,111,114,32,97,32,109,111,
+ 100,117,108,101,32,115,112,101,99,105,102,105,101,100,32,98,
+ 121,32,39,102,117,108,108,110,97,109,101,39,46,32,39,102,
+ 117,108,108,110,97,109,101,39,32,109,117,115,116,32,98,101,
+ 32,116,104,101,10,32,32,32,32,32,32,32,32,102,117,108,
+ 108,121,32,113,117,97,108,105,102,105,101,100,32,40,100,111,
+ 116,116,101,100,41,32,109,111,100,117,108,101,32,110,97,109,
+ 101,46,32,73,116,32,114,101,116,117,114,110,115,32,116,104,
+ 101,32,122,105,112,105,109,112,111,114,116,101,114,10,32,32,
+ 32,32,32,32,32,32,105,110,115,116,97,110,99,101,32,105,
+ 116,115,101,108,102,32,105,102,32,116,104,101,32,109,111,100,
+ 117,108,101,32,119,97,115,32,102,111,117,110,100,44,32,97,
+ 32,115,116,114,105,110,103,32,99,111,110,116,97,105,110,105,
+ 110,103,32,116,104,101,10,32,32,32,32,32,32,32,32,102,
+ 117,108,108,32,112,97,116,104,32,110,97,109,101,32,105,102,
+ 32,105,116,39,115,32,112,111,115,115,105,98,108,121,32,97,
+ 32,112,111,114,116,105,111,110,32,111,102,32,97,32,110,97,
+ 109,101,115,112,97,99,101,32,112,97,99,107,97,103,101,44,
+ 10,32,32,32,32,32,32,32,32,111,114,32,78,111,110,101,
+ 32,111,116,104,101,114,119,105,115,101,46,32,84,104,101,32,
+ 111,112,116,105,111,110,97,108,32,39,112,97,116,104,39,32,
+ 97,114,103,117,109,101,110,116,32,105,115,32,105,103,110,111,
+ 114,101,100,32,45,45,32,105,116,39,115,10,32,32,32,32,
+ 32,32,32,32,116,104,101,114,101,32,102,111,114,32,99,111,
+ 109,112,97,116,105,98,105,108,105,116,121,32,119,105,116,104,
+ 32,116,104,101,32,105,109,112,111,114,116,101,114,32,112,114,
+ 111,116,111,99,111,108,46,10,32,32,32,32,32,32,32,32,
+ 78,41,5,218,16,95,103,101,116,95,109,111,100,117,108,101,
+ 95,105,110,102,111,218,16,95,103,101,116,95,109,111,100,117,
+ 108,101,95,112,97,116,104,218,7,95,105,115,95,100,105,114,
+ 114,29,0,0,0,114,20,0,0,0,41,5,114,32,0,0,
+ 0,218,8,102,117,108,108,110,97,109,101,114,13,0,0,0,
+ 218,2,109,105,218,7,109,111,100,112,97,116,104,114,9,0,
+ 0,0,114,9,0,0,0,114,10,0,0,0,218,11,102,105,
+ 110,100,95,108,111,97,100,101,114,109,0,0,0,115,14,0,
+ 0,0,0,10,10,1,8,2,8,7,10,1,10,4,24,2,
+ 122,23,122,105,112,105,109,112,111,114,116,101,114,46,102,105,
+ 110,100,95,108,111,97,100,101,114,99,3,0,0,0,0,0,
+ 0,0,0,0,0,0,3,0,0,0,4,0,0,0,67,0,
+ 0,0,115,16,0,0,0,124,0,160,0,124,1,124,2,161,
+ 2,100,1,25,0,83,0,41,2,97,139,1,0,0,102,105,
+ 110,100,95,109,111,100,117,108,101,40,102,117,108,108,110,97,
+ 109,101,44,32,112,97,116,104,61,78,111,110,101,41,32,45,
+ 62,32,115,101,108,102,32,111,114,32,78,111,110,101,46,10,
+ 10,32,32,32,32,32,32,32,32,83,101,97,114,99,104,32,
+ 102,111,114,32,97,32,109,111,100,117,108,101,32,115,112,101,
+ 99,105,102,105,101,100,32,98,121,32,39,102,117,108,108,110,
+ 97,109,101,39,46,32,39,102,117,108,108,110,97,109,101,39,
+ 32,109,117,115,116,32,98,101,32,116,104,101,10,32,32,32,
+ 32,32,32,32,32,102,117,108,108,121,32,113,117,97,108,105,
+ 102,105,101,100,32,40,100,111,116,116,101,100,41,32,109,111,
+ 100,117,108,101,32,110,97,109,101,46,32,73,116,32,114,101,
+ 116,117,114,110,115,32,116,104,101,32,122,105,112,105,109,112,
+ 111,114,116,101,114,10,32,32,32,32,32,32,32,32,105,110,
+ 115,116,97,110,99,101,32,105,116,115,101,108,102,32,105,102,
+ 32,116,104,101,32,109,111,100,117,108,101,32,119,97,115,32,
+ 102,111,117,110,100,44,32,111,114,32,78,111,110,101,32,105,
+ 102,32,105,116,32,119,97,115,110,39,116,46,10,32,32,32,
+ 32,32,32,32,32,84,104,101,32,111,112,116,105,111,110,97,
+ 108,32,39,112,97,116,104,39,32,97,114,103,117,109,101,110,
+ 116,32,105,115,32,105,103,110,111,114,101,100,32,45,45,32,
+ 105,116,39,115,32,116,104,101,114,101,32,102,111,114,32,99,
+ 111,109,112,97,116,105,98,105,108,105,116,121,10,32,32,32,
+ 32,32,32,32,32,119,105,116,104,32,116,104,101,32,105,109,
+ 112,111,114,116,101,114,32,112,114,111,116,111,99,111,108,46,
+ 10,32,32,32,32,32,32,32,32,114,0,0,0,0,41,1,
+ 114,41,0,0,0,41,3,114,32,0,0,0,114,38,0,0,
+ 0,114,13,0,0,0,114,9,0,0,0,114,9,0,0,0,
+ 114,10,0,0,0,218,11,102,105,110,100,95,109,111,100,117,
+ 108,101,141,0,0,0,115,2,0,0,0,0,9,122,23,122,
+ 105,112,105,109,112,111,114,116,101,114,46,102,105,110,100,95,
+ 109,111,100,117,108,101,99,2,0,0,0,0,0,0,0,0,
+ 0,0,0,5,0,0,0,3,0,0,0,67,0,0,0,115,
+ 20,0,0,0,116,0,124,0,124,1,131,2,92,3,125,2,
+ 125,3,125,4,124,2,83,0,41,1,122,163,103,101,116,95,
+ 99,111,100,101,40,102,117,108,108,110,97,109,101,41,32,45,
+ 62,32,99,111,100,101,32,111,98,106,101,99,116,46,10,10,
+ 32,32,32,32,32,32,32,32,82,101,116,117,114,110,32,116,
+ 104,101,32,99,111,100,101,32,111,98,106,101,99,116,32,102,
+ 111,114,32,116,104,101,32,115,112,101,99,105,102,105,101,100,
+ 32,109,111,100,117,108,101,46,32,82,97,105,115,101,32,90,
+ 105,112,73,109,112,111,114,116,69,114,114,111,114,10,32,32,
+ 32,32,32,32,32,32,105,102,32,116,104,101,32,109,111,100,
+ 117,108,101,32,99,111,117,108,100,110,39,116,32,98,101,32,
+ 102,111,117,110,100,46,10,32,32,32,32,32,32,32,32,169,
+ 1,218,16,95,103,101,116,95,109,111,100,117,108,101,95,99,
+ 111,100,101,169,5,114,32,0,0,0,114,38,0,0,0,218,
+ 4,99,111,100,101,218,9,105,115,112,97,99,107,97,103,101,
+ 114,40,0,0,0,114,9,0,0,0,114,9,0,0,0,114,
+ 10,0,0,0,218,8,103,101,116,95,99,111,100,101,153,0,
+ 0,0,115,4,0,0,0,0,6,16,1,122,20,122,105,112,
+ 105,109,112,111,114,116,101,114,46,103,101,116,95,99,111,100,
+ 101,99,2,0,0,0,0,0,0,0,0,0,0,0,4,0,
+ 0,0,8,0,0,0,67,0,0,0,115,116,0,0,0,116,
+ 0,114,16,124,1,160,1,116,0,116,2,161,2,125,1,124,
+ 1,125,2,124,1,160,3,124,0,106,4,116,2,23,0,161,
+ 1,114,58,124,1,116,5,124,0,106,4,116,2,23,0,131,
+ 1,100,1,133,2,25,0,125,2,122,14,124,0,106,6,124,
+ 2,25,0,125,3,87,0,110,30,4,0,116,7,121,102,1,
+ 0,1,0,1,0,116,8,100,2,100,3,124,2,131,3,130,
+ 1,89,0,110,2,48,0,116,9,124,0,106,4,124,3,131,
+ 2,83,0,41,4,122,154,103,101,116,95,100,97,116,97,40,
+ 112,97,116,104,110,97,109,101,41,32,45,62,32,115,116,114,
+ 105,110,103,32,119,105,116,104,32,102,105,108,101,32,100,97,
+ 116,97,46,10,10,32,32,32,32,32,32,32,32,82,101,116,
+ 117,114,110,32,116,104,101,32,100,97,116,97,32,97,115,115,
+ 111,99,105,97,116,101,100,32,119,105,116,104,32,39,112,97,
+ 116,104,110,97,109,101,39,46,32,82,97,105,115,101,32,79,
+ 83,69,114,114,111,114,32,105,102,10,32,32,32,32,32,32,
+ 32,32,116,104,101,32,102,105,108,101,32,119,97,115,110,39,
+ 116,32,102,111,117,110,100,46,10,32,32,32,32,32,32,32,
+ 32,78,114,0,0,0,0,218,0,41,10,114,18,0,0,0,
+ 114,19,0,0,0,114,20,0,0,0,218,10,115,116,97,114,
+ 116,115,119,105,116,104,114,29,0,0,0,218,3,108,101,110,
+ 114,28,0,0,0,114,26,0,0,0,114,22,0,0,0,218,
+ 9,95,103,101,116,95,100,97,116,97,41,4,114,32,0,0,
+ 0,218,8,112,97,116,104,110,97,109,101,90,3,107,101,121,
+ 218,9,116,111,99,95,101,110,116,114,121,114,9,0,0,0,
+ 114,9,0,0,0,114,10,0,0,0,218,8,103,101,116,95,
+ 100,97,116,97,163,0,0,0,115,20,0,0,0,0,6,4,
+ 1,12,2,4,1,16,1,22,2,2,1,14,1,12,1,18,
+ 1,122,20,122,105,112,105,109,112,111,114,116,101,114,46,103,
+ 101,116,95,100,97,116,97,99,2,0,0,0,0,0,0,0,
+ 0,0,0,0,5,0,0,0,3,0,0,0,67,0,0,0,
+ 115,20,0,0,0,116,0,124,0,124,1,131,2,92,3,125,
+ 2,125,3,125,4,124,4,83,0,41,1,122,106,103,101,116,
+ 95,102,105,108,101,110,97,109,101,40,102,117,108,108,110,97,
+ 109,101,41,32,45,62,32,102,105,108,101,110,97,109,101,32,
+ 115,116,114,105,110,103,46,10,10,32,32,32,32,32,32,32,
+ 32,82,101,116,117,114,110,32,116,104,101,32,102,105,108,101,
+ 110,97,109,101,32,102,111,114,32,116,104,101,32,115,112,101,
+ 99,105,102,105,101,100,32,109,111,100,117,108,101,46,10,32,
+ 32,32,32,32,32,32,32,114,43,0,0,0,114,45,0,0,
+ 0,114,9,0,0,0,114,9,0,0,0,114,10,0,0,0,
+ 218,12,103,101,116,95,102,105,108,101,110,97,109,101,184,0,
+ 0,0,115,4,0,0,0,0,7,16,1,122,24,122,105,112,
+ 105,109,112,111,114,116,101,114,46,103,101,116,95,102,105,108,
+ 101,110,97,109,101,99,2,0,0,0,0,0,0,0,0,0,
+ 0,0,6,0,0,0,8,0,0,0,67,0,0,0,115,126,
+ 0,0,0,116,0,124,0,124,1,131,2,125,2,124,2,100,
+ 1,117,0,114,36,116,1,100,2,124,1,155,2,157,2,124,
+ 1,100,3,141,2,130,1,116,2,124,0,124,1,131,2,125,
+ 3,124,2,114,64,116,3,160,4,124,3,100,4,161,2,125,
+ 4,110,10,124,3,155,0,100,5,157,2,125,4,122,14,124,
+ 0,106,5,124,4,25,0,125,5,87,0,110,20,4,0,116,
+ 6,121,108,1,0,1,0,1,0,89,0,100,1,83,0,48,
+ 0,116,7,124,0,106,8,124,5,131,2,160,9,161,0,83,
+ 0,41,6,122,253,103,101,116,95,115,111,117,114,99,101,40,
+ 102,117,108,108,110,97,109,101,41,32,45,62,32,115,111,117,
+ 114,99,101,32,115,116,114,105,110,103,46,10,10,32,32,32,
+ 32,32,32,32,32,82,101,116,117,114,110,32,116,104,101,32,
+ 115,111,117,114,99,101,32,99,111,100,101,32,102,111,114,32,
+ 116,104,101,32,115,112,101,99,105,102,105,101,100,32,109,111,
+ 100,117,108,101,46,32,82,97,105,115,101,32,90,105,112,73,
+ 109,112,111,114,116,69,114,114,111,114,10,32,32,32,32,32,
+ 32,32,32,105,102,32,116,104,101,32,109,111,100,117,108,101,
+ 32,99,111,117,108,100,110,39,116,32,98,101,32,102,111,117,
+ 110,100,44,32,114,101,116,117,114,110,32,78,111,110,101,32,
+ 105,102,32,116,104,101,32,97,114,99,104,105,118,101,32,100,
+ 111,101,115,10,32,32,32,32,32,32,32,32,99,111,110,116,
+ 97,105,110,32,116,104,101,32,109,111,100,117,108,101,44,32,
+ 98,117,116,32,104,97,115,32,110,111,32,115,111,117,114,99,
+ 101,32,102,111,114,32,105,116,46,10,32,32,32,32,32,32,
+ 32,32,78,250,18,99,97,110,39,116,32,102,105,110,100,32,
+ 109,111,100,117,108,101,32,169,1,218,4,110,97,109,101,250,
+ 11,95,95,105,110,105,116,95,95,46,112,121,250,3,46,112,
+ 121,41,10,114,35,0,0,0,114,3,0,0,0,114,36,0,
+ 0,0,114,21,0,0,0,114,30,0,0,0,114,28,0,0,
+ 0,114,26,0,0,0,114,52,0,0,0,114,29,0,0,0,
+ 218,6,100,101,99,111,100,101,41,6,114,32,0,0,0,114,
+ 38,0,0,0,114,39,0,0,0,114,13,0,0,0,218,8,
+ 102,117,108,108,112,97,116,104,114,54,0,0,0,114,9,0,
+ 0,0,114,9,0,0,0,114,10,0,0,0,218,10,103,101,
+ 116,95,115,111,117,114,99,101,195,0,0,0,115,24,0,0,
+ 0,0,7,10,1,8,1,18,2,10,1,4,1,14,2,10,
+ 2,2,1,14,1,12,2,8,1,122,22,122,105,112,105,109,
+ 112,111,114,116,101,114,46,103,101,116,95,115,111,117,114,99,
+ 101,99,2,0,0,0,0,0,0,0,0,0,0,0,3,0,
+ 0,0,4,0,0,0,67,0,0,0,115,40,0,0,0,116,
+ 0,124,0,124,1,131,2,125,2,124,2,100,1,117,0,114,
+ 36,116,1,100,2,124,1,155,2,157,2,124,1,100,3,141,
+ 2,130,1,124,2,83,0,41,4,122,171,105,115,95,112,97,
+ 99,107,97,103,101,40,102,117,108,108,110,97,109,101,41,32,
+ 45,62,32,98,111,111,108,46,10,10,32,32,32,32,32,32,
+ 32,32,82,101,116,117,114,110,32,84,114,117,101,32,105,102,
+ 32,116,104,101,32,109,111,100,117,108,101,32,115,112,101,99,
+ 105,102,105,101,100,32,98,121,32,102,117,108,108,110,97,109,
+ 101,32,105,115,32,97,32,112,97,99,107,97,103,101,46,10,
+ 32,32,32,32,32,32,32,32,82,97,105,115,101,32,90,105,
+ 112,73,109,112,111,114,116,69,114,114,111,114,32,105,102,32,
+ 116,104,101,32,109,111,100,117,108,101,32,99,111,117,108,100,
+ 110,39,116,32,98,101,32,102,111,117,110,100,46,10,32,32,
+ 32,32,32,32,32,32,78,114,57,0,0,0,114,58,0,0,
+ 0,41,2,114,35,0,0,0,114,3,0,0,0,41,3,114,
+ 32,0,0,0,114,38,0,0,0,114,39,0,0,0,114,9,
+ 0,0,0,114,9,0,0,0,114,10,0,0,0,218,10,105,
+ 115,95,112,97,99,107,97,103,101,221,0,0,0,115,8,0,
+ 0,0,0,6,10,1,8,1,18,1,122,22,122,105,112,105,
+ 109,112,111,114,116,101,114,46,105,115,95,112,97,99,107,97,
+ 103,101,99,2,0,0,0,0,0,0,0,0,0,0,0,8,
+ 0,0,0,8,0,0,0,67,0,0,0,115,246,0,0,0,
+ 116,0,124,0,124,1,131,2,92,3,125,2,125,3,125,4,
+ 116,1,106,2,160,3,124,1,161,1,125,5,124,5,100,1,
+ 117,0,115,46,116,4,124,5,116,5,131,2,115,64,116,5,
+ 124,1,131,1,125,5,124,5,116,1,106,2,124,1,60,0,
+ 124,0,124,5,95,6,122,84,124,3,114,108,116,7,124,0,
+ 124,1,131,2,125,6,116,8,160,9,124,0,106,10,124,6,
+ 161,2,125,7,124,7,103,1,124,5,95,11,116,12,124,5,
+ 100,2,131,2,115,124,116,13,124,5,95,13,116,8,160,14,
+ 124,5,106,15,124,1,124,4,161,3,1,0,116,16,124,2,
+ 124,5,106,15,131,2,1,0,87,0,110,22,1,0,1,0,
+ 1,0,116,1,106,2,124,1,61,0,130,0,89,0,110,2,
+ 48,0,122,14,116,1,106,2,124,1,25,0,125,5,87,0,
+ 110,34,4,0,116,17,121,226,1,0,1,0,1,0,116,18,
+ 100,3,124,1,155,2,100,4,157,3,131,1,130,1,89,0,
+ 110,2,48,0,116,19,160,20,100,5,124,1,124,4,161,3,
+ 1,0,124,5,83,0,41,6,122,245,108,111,97,100,95,109,
+ 111,100,117,108,101,40,102,117,108,108,110,97,109,101,41,32,
+ 45,62,32,109,111,100,117,108,101,46,10,10,32,32,32,32,
+ 32,32,32,32,76,111,97,100,32,116,104,101,32,109,111,100,
+ 117,108,101,32,115,112,101,99,105,102,105,101,100,32,98,121,
+ 32,39,102,117,108,108,110,97,109,101,39,46,32,39,102,117,
+ 108,108,110,97,109,101,39,32,109,117,115,116,32,98,101,32,
+ 116,104,101,10,32,32,32,32,32,32,32,32,102,117,108,108,
+ 121,32,113,117,97,108,105,102,105,101,100,32,40,100,111,116,
+ 116,101,100,41,32,109,111,100,117,108,101,32,110,97,109,101,
+ 46,32,73,116,32,114,101,116,117,114,110,115,32,116,104,101,
+ 32,105,109,112,111,114,116,101,100,10,32,32,32,32,32,32,
+ 32,32,109,111,100,117,108,101,44,32,111,114,32,114,97,105,
+ 115,101,115,32,90,105,112,73,109,112,111,114,116,69,114,114,
+ 111,114,32,105,102,32,105,116,32,119,97,115,110,39,116,32,
+ 102,111,117,110,100,46,10,32,32,32,32,32,32,32,32,78,
+ 218,12,95,95,98,117,105,108,116,105,110,115,95,95,122,14,
+ 76,111,97,100,101,100,32,109,111,100,117,108,101,32,122,25,
+ 32,110,111,116,32,102,111,117,110,100,32,105,110,32,115,121,
+ 115,46,109,111,100,117,108,101,115,122,30,105,109,112,111,114,
+ 116,32,123,125,32,35,32,108,111,97,100,101,100,32,102,114,
+ 111,109,32,90,105,112,32,123,125,41,21,114,44,0,0,0,
+ 218,3,115,121,115,218,7,109,111,100,117,108,101,115,218,3,
+ 103,101,116,114,15,0,0,0,218,12,95,109,111,100,117,108,
+ 101,95,116,121,112,101,218,10,95,95,108,111,97,100,101,114,
+ 95,95,114,36,0,0,0,114,21,0,0,0,114,30,0,0,
+ 0,114,29,0,0,0,90,8,95,95,112,97,116,104,95,95,
+ 218,7,104,97,115,97,116,116,114,114,66,0,0,0,90,14,
+ 95,102,105,120,95,117,112,95,109,111,100,117,108,101,218,8,
+ 95,95,100,105,99,116,95,95,218,4,101,120,101,99,114,26,
+ 0,0,0,218,11,73,109,112,111,114,116,69,114,114,111,114,
+ 218,10,95,98,111,111,116,115,116,114,97,112,218,16,95,118,
+ 101,114,98,111,115,101,95,109,101,115,115,97,103,101,41,8,
+ 114,32,0,0,0,114,38,0,0,0,114,46,0,0,0,114,
+ 47,0,0,0,114,40,0,0,0,90,3,109,111,100,114,13,
+ 0,0,0,114,63,0,0,0,114,9,0,0,0,114,9,0,
+ 0,0,114,10,0,0,0,218,11,108,111,97,100,95,109,111,
+ 100,117,108,101,234,0,0,0,115,48,0,0,0,0,7,16,
+ 1,12,1,18,1,8,1,10,1,6,2,2,1,4,3,10,
+ 1,14,1,8,2,10,1,6,1,16,1,16,1,6,1,8,
+ 1,8,2,2,1,14,1,12,1,22,1,14,1,122,23,122,
+ 105,112,105,109,112,111,114,116,101,114,46,108,111,97,100,95,
+ 109,111,100,117,108,101,99,2,0,0,0,0,0,0,0,0,
+ 0,0,0,3,0,0,0,8,0,0,0,67,0,0,0,115,
+ 86,0,0,0,122,20,124,0,160,0,124,1,161,1,115,18,
+ 87,0,100,1,83,0,87,0,110,20,4,0,116,1,121,40,
+ 1,0,1,0,1,0,89,0,100,1,83,0,48,0,116,2,
+ 106,3,115,76,100,2,100,3,108,4,109,5,125,2,1,0,
+ 124,2,160,6,116,2,161,1,1,0,100,4,116,2,95,3,
+ 116,2,124,0,124,1,131,2,83,0,41,5,122,204,82,101,
+ 116,117,114,110,32,116,104,101,32,82,101,115,111,117,114,99,
+ 101,82,101,97,100,101,114,32,102,111,114,32,97,32,112,97,
+ 99,107,97,103,101,32,105,110,32,97,32,122,105,112,32,102,
+ 105,108,101,46,10,10,32,32,32,32,32,32,32,32,73,102,
+ 32,39,102,117,108,108,110,97,109,101,39,32,105,115,32,97,
+ 32,112,97,99,107,97,103,101,32,119,105,116,104,105,110,32,
+ 116,104,101,32,122,105,112,32,102,105,108,101,44,32,114,101,
+ 116,117,114,110,32,116,104,101,10,32,32,32,32,32,32,32,
+ 32,39,82,101,115,111,117,114,99,101,82,101,97,100,101,114,
+ 39,32,111,98,106,101,99,116,32,102,111,114,32,116,104,101,
+ 32,112,97,99,107,97,103,101,46,32,32,79,116,104,101,114,
+ 119,105,115,101,32,114,101,116,117,114,110,32,78,111,110,101,
+ 46,10,32,32,32,32,32,32,32,32,78,114,0,0,0,0,
+ 41,1,218,14,82,101,115,111,117,114,99,101,82,101,97,100,
+ 101,114,84,41,7,114,65,0,0,0,114,3,0,0,0,218,
+ 24,95,90,105,112,73,109,112,111,114,116,82,101,115,111,117,
+ 114,99,101,82,101,97,100,101,114,218,11,95,114,101,103,105,
+ 115,116,101,114,101,100,90,13,105,109,112,111,114,116,108,105,
+ 98,46,97,98,99,114,79,0,0,0,90,8,114,101,103,105,
+ 115,116,101,114,41,3,114,32,0,0,0,114,38,0,0,0,
+ 114,79,0,0,0,114,9,0,0,0,114,9,0,0,0,114,
+ 10,0,0,0,218,19,103,101,116,95,114,101,115,111,117,114,
+ 99,101,95,114,101,97,100,101,114,16,1,0,0,115,20,0,
+ 0,0,0,6,2,1,10,1,10,1,12,1,8,1,6,1,
+ 12,1,10,1,6,1,122,31,122,105,112,105,109,112,111,114,
+ 116,101,114,46,103,101,116,95,114,101,115,111,117,114,99,101,
+ 95,114,101,97,100,101,114,99,1,0,0,0,0,0,0,0,
+ 0,0,0,0,1,0,0,0,5,0,0,0,67,0,0,0,
+ 115,24,0,0,0,100,1,124,0,106,0,155,0,116,1,155,
+ 0,124,0,106,2,155,0,100,2,157,5,83,0,41,3,78,
+ 122,21,60,122,105,112,105,109,112,111,114,116,101,114,32,111,
+ 98,106,101,99,116,32,34,122,2,34,62,41,3,114,29,0,
+ 0,0,114,20,0,0,0,114,31,0,0,0,41,1,114,32,
+ 0,0,0,114,9,0,0,0,114,9,0,0,0,114,10,0,
+ 0,0,218,8,95,95,114,101,112,114,95,95,34,1,0,0,
+ 115,2,0,0,0,0,1,122,20,122,105,112,105,109,112,111,
+ 114,116,101,114,46,95,95,114,101,112,114,95,95,41,1,78,
+ 41,1,78,41,15,114,6,0,0,0,114,7,0,0,0,114,
+ 8,0,0,0,218,7,95,95,100,111,99,95,95,114,34,0,
+ 0,0,114,41,0,0,0,114,42,0,0,0,114,48,0,0,
+ 0,114,55,0,0,0,114,56,0,0,0,114,64,0,0,0,
+ 114,65,0,0,0,114,78,0,0,0,114,82,0,0,0,114,
+ 83,0,0,0,114,9,0,0,0,114,9,0,0,0,114,9,
+ 0,0,0,114,10,0,0,0,114,4,0,0,0,45,0,0,
+ 0,115,24,0,0,0,8,1,4,17,8,46,10,32,10,12,
+ 8,10,8,21,8,11,8,26,8,13,8,38,8,18,122,12,
+ 95,95,105,110,105,116,95,95,46,112,121,99,84,114,60,0,
+ 0,0,70,41,3,122,4,46,112,121,99,84,70,41,3,114,
+ 61,0,0,0,70,70,99,2,0,0,0,0,0,0,0,0,
+ 0,0,0,2,0,0,0,4,0,0,0,67,0,0,0,115,
+ 20,0,0,0,124,0,106,0,124,1,160,1,100,1,161,1,
+ 100,2,25,0,23,0,83,0,41,3,78,218,1,46,233,2,
+ 0,0,0,41,2,114,31,0,0,0,218,10,114,112,97,114,
+ 116,105,116,105,111,110,41,2,114,32,0,0,0,114,38,0,
+ 0,0,114,9,0,0,0,114,9,0,0,0,114,10,0,0,
+ 0,114,36,0,0,0,52,1,0,0,115,2,0,0,0,0,
+ 1,114,36,0,0,0,99,2,0,0,0,0,0,0,0,0,
+ 0,0,0,3,0,0,0,2,0,0,0,67,0,0,0,115,
+ 18,0,0,0,124,1,116,0,23,0,125,2,124,2,124,0,
+ 106,1,118,0,83,0,169,1,78,41,2,114,20,0,0,0,
+ 114,28,0,0,0,41,3,114,32,0,0,0,114,13,0,0,
+ 0,90,7,100,105,114,112,97,116,104,114,9,0,0,0,114,
+ 9,0,0,0,114,10,0,0,0,114,37,0,0,0,56,1,
+ 0,0,115,4,0,0,0,0,4,8,2,114,37,0,0,0,
+ 99,2,0,0,0,0,0,0,0,0,0,0,0,7,0,0,
+ 0,4,0,0,0,67,0,0,0,115,56,0,0,0,116,0,
+ 124,0,124,1,131,2,125,2,116,1,68,0,93,36,92,3,
+ 125,3,125,4,125,5,124,2,124,3,23,0,125,6,124,6,
+ 124,0,106,2,118,0,114,14,124,5,2,0,1,0,83,0,
+ 113,14,100,0,83,0,114,88,0,0,0,41,3,114,36,0,
+ 0,0,218,16,95,122,105,112,95,115,101,97,114,99,104,111,
+ 114,100,101,114,114,28,0,0,0,41,7,114,32,0,0,0,
+ 114,38,0,0,0,114,13,0,0,0,218,6,115,117,102,102,
+ 105,120,218,10,105,115,98,121,116,101,99,111,100,101,114,47,
+ 0,0,0,114,63,0,0,0,114,9,0,0,0,114,9,0,
+ 0,0,114,10,0,0,0,114,35,0,0,0,65,1,0,0,
+ 115,12,0,0,0,0,1,10,1,14,1,8,1,10,1,10,
+ 1,114,35,0,0,0,99,1,0,0,0,0,0,0,0,0,
+ 0,0,0,26,0,0,0,9,0,0,0,67,0,0,0,115,
+ 2,5,0,0,122,14,116,0,160,1,124,0,161,1,125,1,
+ 87,0,110,36,4,0,116,2,121,50,1,0,1,0,1,0,
+ 116,3,100,1,124,0,155,2,157,2,124,0,100,2,141,2,
+ 130,1,89,0,110,2,48,0,124,1,144,4,143,164,1,0,
+ 122,36,124,1,160,4,116,5,11,0,100,3,161,2,1,0,
+ 124,1,160,6,161,0,125,2,124,1,160,7,116,5,161,1,
+ 125,3,87,0,110,36,4,0,116,2,121,132,1,0,1,0,
+ 1,0,116,3,100,4,124,0,155,2,157,2,124,0,100,2,
+ 141,2,130,1,89,0,110,2,48,0,116,8,124,3,131,1,
+ 116,5,107,3,114,164,116,3,100,4,124,0,155,2,157,2,
+ 124,0,100,2,141,2,130,1,124,3,100,0,100,5,133,2,
+ 25,0,116,9,107,3,144,1,114,170,122,24,124,1,160,4,
+ 100,6,100,3,161,2,1,0,124,1,160,6,161,0,125,4,
+ 87,0,110,36,4,0,116,2,121,242,1,0,1,0,1,0,
+ 116,3,100,4,124,0,155,2,157,2,124,0,100,2,141,2,
+ 130,1,89,0,110,2,48,0,116,10,124,4,116,11,24,0,
+ 116,5,24,0,100,6,131,2,125,5,122,22,124,1,160,4,
+ 124,5,161,1,1,0,124,1,160,7,161,0,125,6,87,0,
+ 110,38,4,0,116,2,144,1,121,66,1,0,1,0,1,0,
+ 116,3,100,4,124,0,155,2,157,2,124,0,100,2,141,2,
+ 130,1,89,0,110,2,48,0,124,6,160,12,116,9,161,1,
+ 125,7,124,7,100,6,107,0,144,1,114,106,116,3,100,7,
+ 124,0,155,2,157,2,124,0,100,2,141,2,130,1,124,6,
+ 124,7,124,7,116,5,23,0,133,2,25,0,125,3,116,8,
+ 124,3,131,1,116,5,107,3,144,1,114,154,116,3,100,8,
+ 124,0,155,2,157,2,124,0,100,2,141,2,130,1,124,4,
+ 116,8,124,6,131,1,24,0,124,7,23,0,125,2,116,13,
+ 124,3,100,9,100,10,133,2,25,0,131,1,125,8,116,13,
+ 124,3,100,10,100,11,133,2,25,0,131,1,125,9,124,2,
+ 124,8,107,0,144,1,114,230,116,3,100,12,124,0,155,2,
+ 157,2,124,0,100,2,141,2,130,1,124,2,124,9,107,0,
+ 144,2,114,2,116,3,100,13,124,0,155,2,157,2,124,0,
+ 100,2,141,2,130,1,124,2,124,8,56,0,125,2,124,2,
+ 124,9,24,0,125,10,124,10,100,6,107,0,144,2,114,46,
+ 116,3,100,14,124,0,155,2,157,2,124,0,100,2,141,2,
+ 130,1,105,0,125,11,100,6,125,12,122,14,124,1,160,4,
+ 124,2,161,1,1,0,87,0,110,38,4,0,116,2,144,2,
+ 121,106,1,0,1,0,1,0,116,3,100,4,124,0,155,2,
+ 157,2,124,0,100,2,141,2,130,1,89,0,110,2,48,0,
+ 124,1,160,7,100,15,161,1,125,3,116,8,124,3,131,1,
+ 100,5,107,0,144,2,114,140,116,14,100,16,131,1,130,1,
+ 124,3,100,0,100,5,133,2,25,0,100,17,107,3,144,2,
+ 114,162,144,4,113,208,116,8,124,3,131,1,100,15,107,3,
+ 144,2,114,184,116,14,100,16,131,1,130,1,116,15,124,3,
+ 100,18,100,19,133,2,25,0,131,1,125,13,116,15,124,3,
+ 100,19,100,9,133,2,25,0,131,1,125,14,116,15,124,3,
+ 100,9,100,20,133,2,25,0,131,1,125,15,116,15,124,3,
+ 100,20,100,10,133,2,25,0,131,1,125,16,116,13,124,3,
+ 100,10,100,11,133,2,25,0,131,1,125,17,116,13,124,3,
+ 100,11,100,21,133,2,25,0,131,1,125,18,116,13,124,3,
+ 100,21,100,22,133,2,25,0,131,1,125,4,116,15,124,3,
+ 100,22,100,23,133,2,25,0,131,1,125,19,116,15,124,3,
+ 100,23,100,24,133,2,25,0,131,1,125,20,116,15,124,3,
+ 100,24,100,25,133,2,25,0,131,1,125,21,116,13,124,3,
+ 100,26,100,15,133,2,25,0,131,1,125,22,124,19,124,20,
+ 23,0,124,21,23,0,125,8,124,22,124,9,107,4,144,3,
+ 114,144,116,3,100,27,124,0,155,2,157,2,124,0,100,2,
+ 141,2,130,1,124,22,124,10,55,0,125,22,122,14,124,1,
+ 160,7,124,19,161,1,125,23,87,0,110,38,4,0,116,2,
+ 144,3,121,204,1,0,1,0,1,0,116,3,100,4,124,0,
+ 155,2,157,2,124,0,100,2,141,2,130,1,89,0,110,2,
+ 48,0,116,8,124,23,131,1,124,19,107,3,144,3,114,238,
+ 116,3,100,4,124,0,155,2,157,2,124,0,100,2,141,2,
+ 130,1,122,50,116,8,124,1,160,7,124,8,124,19,24,0,
+ 161,1,131,1,124,8,124,19,24,0,107,3,144,4,114,30,
+ 116,3,100,4,124,0,155,2,157,2,124,0,100,2,141,2,
+ 130,1,87,0,110,38,4,0,116,2,144,4,121,70,1,0,
+ 1,0,1,0,116,3,100,4,124,0,155,2,157,2,124,0,
+ 100,2,141,2,130,1,89,0,110,2,48,0,124,13,100,28,
+ 64,0,144,4,114,92,124,23,160,16,161,0,125,23,110,52,
+ 122,14,124,23,160,16,100,29,161,1,125,23,87,0,110,36,
+ 4,0,116,17,144,4,121,142,1,0,1,0,1,0,124,23,
+ 160,16,100,30,161,1,160,18,116,19,161,1,125,23,89,0,
+ 110,2,48,0,124,23,160,20,100,31,116,21,161,2,125,23,
+ 116,22,160,23,124,0,124,23,161,2,125,24,124,24,124,14,
+ 124,18,124,4,124,22,124,15,124,16,124,17,102,8,125,25,
+ 124,25,124,11,124,23,60,0,124,12,100,32,55,0,125,12,
+ 144,2,113,108,87,0,100,0,4,0,4,0,131,3,1,0,
+ 110,18,49,0,144,4,115,230,48,0,1,0,1,0,1,0,
+ 89,0,1,0,116,24,160,25,100,33,124,12,124,0,161,3,
+ 1,0,124,11,83,0,41,34,78,122,21,99,97,110,39,116,
+ 32,111,112,101,110,32,90,105,112,32,102,105,108,101,58,32,
+ 114,12,0,0,0,114,86,0,0,0,250,21,99,97,110,39,
+ 116,32,114,101,97,100,32,90,105,112,32,102,105,108,101,58,
+ 32,233,4,0,0,0,114,0,0,0,0,122,16,110,111,116,
+ 32,97,32,90,105,112,32,102,105,108,101,58,32,122,18,99,
+ 111,114,114,117,112,116,32,90,105,112,32,102,105,108,101,58,
+ 32,233,12,0,0,0,233,16,0,0,0,233,20,0,0,0,
+ 122,28,98,97,100,32,99,101,110,116,114,97,108,32,100,105,
+ 114,101,99,116,111,114,121,32,115,105,122,101,58,32,122,30,
+ 98,97,100,32,99,101,110,116,114,97,108,32,100,105,114,101,
+ 99,116,111,114,121,32,111,102,102,115,101,116,58,32,122,38,
+ 98,97,100,32,99,101,110,116,114,97,108,32,100,105,114,101,
+ 99,116,111,114,121,32,115,105,122,101,32,111,114,32,111,102,
+ 102,115,101,116,58,32,233,46,0,0,0,250,27,69,79,70,
+ 32,114,101,97,100,32,119,104,101,114,101,32,110,111,116,32,
+ 101,120,112,101,99,116,101,100,115,4,0,0,0,80,75,1,
+ 2,233,8,0,0,0,233,10,0,0,0,233,14,0,0,0,
+ 233,24,0,0,0,233,28,0,0,0,233,30,0,0,0,233,
+ 32,0,0,0,233,34,0,0,0,233,42,0,0,0,122,25,
+ 98,97,100,32,108,111,99,97,108,32,104,101,97,100,101,114,
+ 32,111,102,102,115,101,116,58,32,105,0,8,0,0,218,5,
+ 97,115,99,105,105,90,6,108,97,116,105,110,49,250,1,47,
+ 114,5,0,0,0,122,33,122,105,112,105,109,112,111,114,116,
+ 58,32,102,111,117,110,100,32,123,125,32,110,97,109,101,115,
+ 32,105,110,32,123,33,114,125,41,26,218,3,95,105,111,218,
+ 9,111,112,101,110,95,99,111,100,101,114,22,0,0,0,114,
+ 3,0,0,0,218,4,115,101,101,107,218,20,69,78,68,95,
+ 67,69,78,84,82,65,76,95,68,73,82,95,83,73,90,69,
+ 90,4,116,101,108,108,218,4,114,101,97,100,114,51,0,0,
+ 0,218,18,83,84,82,73,78,71,95,69,78,68,95,65,82,
+ 67,72,73,86,69,218,3,109,97,120,218,15,77,65,88,95,
+ 67,79,77,77,69,78,84,95,76,69,78,218,5,114,102,105,
+ 110,100,114,2,0,0,0,218,8,69,79,70,69,114,114,111,
+ 114,114,1,0,0,0,114,62,0,0,0,218,18,85,110,105,
+ 99,111,100,101,68,101,99,111,100,101,69,114,114,111,114,218,
+ 9,116,114,97,110,115,108,97,116,101,218,11,99,112,52,51,
+ 55,95,116,97,98,108,101,114,19,0,0,0,114,20,0,0,
+ 0,114,21,0,0,0,114,30,0,0,0,114,76,0,0,0,
+ 114,77,0,0,0,41,26,114,29,0,0,0,218,2,102,112,
+ 90,15,104,101,97,100,101,114,95,112,111,115,105,116,105,111,
+ 110,218,6,98,117,102,102,101,114,218,9,102,105,108,101,95,
+ 115,105,122,101,90,17,109,97,120,95,99,111,109,109,101,110,
+ 116,95,115,116,97,114,116,218,4,100,97,116,97,90,3,112,
+ 111,115,218,11,104,101,97,100,101,114,95,115,105,122,101,90,
+ 13,104,101,97,100,101,114,95,111,102,102,115,101,116,90,10,
+ 97,114,99,95,111,102,102,115,101,116,114,33,0,0,0,218,
+ 5,99,111,117,110,116,218,5,102,108,97,103,115,218,8,99,
+ 111,109,112,114,101,115,115,218,4,116,105,109,101,218,4,100,
+ 97,116,101,218,3,99,114,99,218,9,100,97,116,97,95,115,
+ 105,122,101,218,9,110,97,109,101,95,115,105,122,101,218,10,
+ 101,120,116,114,97,95,115,105,122,101,90,12,99,111,109,109,
+ 101,110,116,95,115,105,122,101,218,11,102,105,108,101,95,111,
+ 102,102,115,101,116,114,59,0,0,0,114,13,0,0,0,218,
+ 1,116,114,9,0,0,0,114,9,0,0,0,114,10,0,0,
+ 0,114,27,0,0,0,96,1,0,0,115,212,0,0,0,0,
+ 1,2,1,14,1,12,1,24,2,8,1,2,1,14,1,8,
+ 1,14,1,12,1,24,1,12,1,18,1,18,3,2,1,12,
+ 1,12,1,12,1,10,1,2,255,12,2,8,1,2,255,2,
+ 1,2,255,4,2,2,1,10,1,12,1,14,1,10,1,2,
+ 255,12,2,10,1,10,1,10,1,2,255,6,2,16,1,14,
+ 1,10,1,2,255,6,2,16,2,16,1,16,1,10,1,18,
+ 1,10,1,18,1,8,1,8,1,10,1,18,2,4,2,4,
+ 1,2,1,14,1,14,1,24,2,10,1,14,1,8,2,18,
+ 1,4,1,14,1,8,1,16,1,16,1,16,1,16,1,16,
+ 1,16,1,16,1,16,1,16,1,16,1,16,1,12,1,10,
+ 1,18,1,8,2,2,1,14,1,14,1,24,1,14,1,18,
+ 4,2,1,28,1,22,1,14,1,24,2,10,2,10,3,2,
+ 1,14,1,14,1,22,2,12,1,12,1,20,1,8,1,44,
+ 1,14,1,114,27,0,0,0,117,190,1,0,0,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,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,112,113,114,
+ 115,116,117,118,119,120,121,122,123,124,125,126,127,195,135,195,
+ 188,195,169,195,162,195,164,195,160,195,165,195,167,195,170,195,
+ 171,195,168,195,175,195,174,195,172,195,132,195,133,195,137,195,
+ 166,195,134,195,180,195,182,195,178,195,187,195,185,195,191,195,
+ 150,195,156,194,162,194,163,194,165,226,130,167,198,146,195,161,
+ 195,173,195,179,195,186,195,177,195,145,194,170,194,186,194,191,
+ 226,140,144,194,172,194,189,194,188,194,161,194,171,194,187,226,
+ 150,145,226,150,146,226,150,147,226,148,130,226,148,164,226,149,
+ 161,226,149,162,226,149,150,226,149,149,226,149,163,226,149,145,
+ 226,149,151,226,149,157,226,149,156,226,149,155,226,148,144,226,
+ 148,148,226,148,180,226,148,172,226,148,156,226,148,128,226,148,
+ 188,226,149,158,226,149,159,226,149,154,226,149,148,226,149,169,
+ 226,149,166,226,149,160,226,149,144,226,149,172,226,149,167,226,
+ 149,168,226,149,164,226,149,165,226,149,153,226,149,152,226,149,
+ 146,226,149,147,226,149,171,226,149,170,226,148,152,226,148,140,
+ 226,150,136,226,150,132,226,150,140,226,150,144,226,150,128,206,
+ 177,195,159,206,147,207,128,206,163,207,131,194,181,207,132,206,
+ 166,206,152,206,169,206,180,226,136,158,207,134,206,181,226,136,
+ 169,226,137,161,194,177,226,137,165,226,137,164,226,140,160,226,
+ 140,161,195,183,226,137,136,194,176,226,136,153,194,183,226,136,
+ 154,226,129,191,194,178,226,150,160,194,160,99,0,0,0,0,
+ 0,0,0,0,0,0,0,0,1,0,0,0,8,0,0,0,
+ 67,0,0,0,115,110,0,0,0,116,0,114,22,116,1,160,
+ 2,100,1,161,1,1,0,116,3,100,2,131,1,130,1,100,
+ 3,97,0,122,62,122,16,100,4,100,5,108,4,109,5,125,
+ 0,1,0,87,0,110,36,4,0,116,6,121,80,1,0,1,
+ 0,1,0,116,1,160,2,100,1,161,1,1,0,116,3,100,
+ 2,131,1,130,1,89,0,110,2,48,0,87,0,100,6,97,
+ 0,110,6,100,6,97,0,48,0,116,1,160,2,100,7,161,
+ 1,1,0,124,0,83,0,41,8,78,122,27,122,105,112,105,
+ 109,112,111,114,116,58,32,122,108,105,98,32,85,78,65,86,
+ 65,73,76,65,66,76,69,250,41,99,97,110,39,116,32,100,
+ 101,99,111,109,112,114,101,115,115,32,100,97,116,97,59,32,
+ 122,108,105,98,32,110,111,116,32,97,118,97,105,108,97,98,
+ 108,101,84,114,0,0,0,0,169,1,218,10,100,101,99,111,
+ 109,112,114,101,115,115,70,122,25,122,105,112,105,109,112,111,
+ 114,116,58,32,122,108,105,98,32,97,118,97,105,108,97,98,
+ 108,101,41,7,218,15,95,105,109,112,111,114,116,105,110,103,
+ 95,122,108,105,98,114,76,0,0,0,114,77,0,0,0,114,
+ 3,0,0,0,90,4,122,108,105,98,114,141,0,0,0,218,
+ 9,69,120,99,101,112,116,105,111,110,114,140,0,0,0,114,
+ 9,0,0,0,114,9,0,0,0,114,10,0,0,0,218,20,
+ 95,103,101,116,95,100,101,99,111,109,112,114,101,115,115,95,
+ 102,117,110,99,254,1,0,0,115,24,0,0,0,0,2,4,
+ 3,10,1,8,2,4,1,4,1,16,1,12,1,10,1,16,
+ 2,12,2,10,1,114,144,0,0,0,99,2,0,0,0,0,
+ 0,0,0,0,0,0,0,17,0,0,0,9,0,0,0,67,
+ 0,0,0,115,144,1,0,0,124,1,92,8,125,2,125,3,
+ 125,4,125,5,125,6,125,7,125,8,125,9,124,4,100,1,
+ 107,0,114,36,116,0,100,2,131,1,130,1,116,1,160,2,
+ 124,0,161,1,144,1,143,14,125,10,122,14,124,10,160,3,
+ 124,6,161,1,1,0,87,0,110,36,4,0,116,4,121,100,
+ 1,0,1,0,1,0,116,0,100,3,124,0,155,2,157,2,
+ 124,0,100,4,141,2,130,1,89,0,110,2,48,0,124,10,
+ 160,5,100,5,161,1,125,11,116,6,124,11,131,1,100,5,
+ 107,3,114,132,116,7,100,6,131,1,130,1,124,11,100,0,
+ 100,7,133,2,25,0,100,8,107,3,114,166,116,0,100,9,
+ 124,0,155,2,157,2,124,0,100,4,141,2,130,1,116,8,
+ 124,11,100,10,100,11,133,2,25,0,131,1,125,12,116,8,
+ 124,11,100,11,100,5,133,2,25,0,131,1,125,13,100,5,
+ 124,12,23,0,124,13,23,0,125,14,124,6,124,14,55,0,
+ 125,6,122,14,124,10,160,3,124,6,161,1,1,0,87,0,
+ 110,38,4,0,116,4,144,1,121,14,1,0,1,0,1,0,
+ 116,0,100,3,124,0,155,2,157,2,124,0,100,4,141,2,
+ 130,1,89,0,110,2,48,0,124,10,160,5,124,4,161,1,
+ 125,15,116,6,124,15,131,1,124,4,107,3,144,1,114,48,
+ 116,4,100,12,131,1,130,1,87,0,100,0,4,0,4,0,
+ 131,3,1,0,110,18,49,0,144,1,115,70,48,0,1,0,
+ 1,0,1,0,89,0,1,0,124,3,100,1,107,2,144,1,
+ 114,94,124,15,83,0,122,10,116,9,131,0,125,16,87,0,
+ 110,28,4,0,116,10,144,1,121,132,1,0,1,0,1,0,
+ 116,0,100,13,131,1,130,1,89,0,110,2,48,0,124,16,
+ 124,15,100,14,131,2,83,0,41,15,78,114,0,0,0,0,
+ 122,18,110,101,103,97,116,105,118,101,32,100,97,116,97,32,
+ 115,105,122,101,114,92,0,0,0,114,12,0,0,0,114,104,
+ 0,0,0,114,98,0,0,0,114,93,0,0,0,115,4,0,
+ 0,0,80,75,3,4,122,23,98,97,100,32,108,111,99,97,
+ 108,32,102,105,108,101,32,104,101,97,100,101,114,58,32,233,
+ 26,0,0,0,114,103,0,0,0,122,26,122,105,112,105,109,
+ 112,111,114,116,58,32,99,97,110,39,116,32,114,101,97,100,
+ 32,100,97,116,97,114,139,0,0,0,105,241,255,255,255,41,
+ 11,114,3,0,0,0,114,110,0,0,0,114,111,0,0,0,
+ 114,112,0,0,0,114,22,0,0,0,114,114,0,0,0,114,
+ 51,0,0,0,114,119,0,0,0,114,1,0,0,0,114,144,
+ 0,0,0,114,143,0,0,0,41,17,114,29,0,0,0,114,
+ 54,0,0,0,90,8,100,97,116,97,112,97,116,104,114,130,
+ 0,0,0,114,134,0,0,0,114,125,0,0,0,114,137,0,
+ 0,0,114,131,0,0,0,114,132,0,0,0,114,133,0,0,
+ 0,114,123,0,0,0,114,124,0,0,0,114,135,0,0,0,
+ 114,136,0,0,0,114,127,0,0,0,90,8,114,97,119,95,
+ 100,97,116,97,114,141,0,0,0,114,9,0,0,0,114,9,
+ 0,0,0,114,10,0,0,0,114,52,0,0,0,19,2,0,
+ 0,115,62,0,0,0,0,1,20,1,8,1,8,2,14,2,
+ 2,1,14,1,12,1,24,1,10,1,12,1,8,2,16,2,
+ 18,2,16,1,16,1,12,1,8,1,2,1,14,1,14,1,
+ 24,1,10,1,14,1,40,2,10,2,4,3,2,1,10,1,
+ 14,1,14,1,114,52,0,0,0,99,2,0,0,0,0,0,
+ 0,0,0,0,0,0,2,0,0,0,3,0,0,0,67,0,
+ 0,0,115,16,0,0,0,116,0,124,0,124,1,24,0,131,
+ 1,100,1,107,1,83,0,41,2,78,114,5,0,0,0,41,
+ 1,218,3,97,98,115,41,2,90,2,116,49,90,2,116,50,
+ 114,9,0,0,0,114,9,0,0,0,114,10,0,0,0,218,
+ 9,95,101,113,95,109,116,105,109,101,65,2,0,0,115,2,
+ 0,0,0,0,2,114,147,0,0,0,99,5,0,0,0,0,
+ 0,0,0,0,0,0,0,14,0,0,0,8,0,0,0,67,
+ 0,0,0,115,56,1,0,0,124,3,124,2,100,1,156,2,
+ 125,5,122,18,116,0,160,1,124,4,124,3,124,5,161,3,
+ 125,6,87,0,110,20,4,0,116,2,121,48,1,0,1,0,
+ 1,0,89,0,100,0,83,0,48,0,124,6,100,2,64,0,
+ 100,3,107,3,125,7,124,7,114,178,124,6,100,4,64,0,
+ 100,3,107,3,125,8,116,3,106,4,100,5,107,3,114,176,
+ 124,8,115,102,116,3,106,4,100,6,107,2,114,176,116,5,
+ 124,0,124,2,131,2,125,9,124,9,100,0,117,1,114,176,
+ 116,3,160,6,116,0,106,7,124,9,161,2,125,10,122,20,
+ 116,0,160,8,124,4,124,10,124,3,124,5,161,4,1,0,
+ 87,0,110,20,4,0,116,2,121,174,1,0,1,0,1,0,
+ 89,0,100,0,83,0,48,0,110,84,116,9,124,0,124,2,
+ 131,2,92,2,125,11,125,12,124,11,144,1,114,6,116,10,
+ 116,11,124,4,100,7,100,8,133,2,25,0,131,1,124,11,
+ 131,2,114,242,116,11,124,4,100,8,100,9,133,2,25,0,
+ 131,1,124,12,107,3,144,1,114,6,116,12,160,13,100,10,
+ 124,3,155,2,157,2,161,1,1,0,100,0,83,0,116,14,
+ 160,15,124,4,100,9,100,0,133,2,25,0,161,1,125,13,
+ 116,16,124,13,116,17,131,2,144,1,115,52,116,18,100,11,
+ 124,1,155,2,100,12,157,3,131,1,130,1,124,13,83,0,
+ 41,13,78,41,2,114,59,0,0,0,114,13,0,0,0,114,
+ 5,0,0,0,114,0,0,0,0,114,86,0,0,0,90,5,
+ 110,101,118,101,114,90,6,97,108,119,97,121,115,114,99,0,
+ 0,0,114,94,0,0,0,114,95,0,0,0,122,22,98,121,
+ 116,101,99,111,100,101,32,105,115,32,115,116,97,108,101,32,
+ 102,111,114,32,122,16,99,111,109,112,105,108,101,100,32,109,
+ 111,100,117,108,101,32,122,21,32,105,115,32,110,111,116,32,
+ 97,32,99,111,100,101,32,111,98,106,101,99,116,41,19,114,
+ 21,0,0,0,90,13,95,99,108,97,115,115,105,102,121,95,
+ 112,121,99,114,75,0,0,0,218,4,95,105,109,112,90,21,
+ 99,104,101,99,107,95,104,97,115,104,95,98,97,115,101,100,
+ 95,112,121,99,115,218,15,95,103,101,116,95,112,121,99,95,
+ 115,111,117,114,99,101,218,11,115,111,117,114,99,101,95,104,
+ 97,115,104,90,17,95,82,65,87,95,77,65,71,73,67,95,
+ 78,85,77,66,69,82,90,18,95,118,97,108,105,100,97,116,
+ 101,95,104,97,115,104,95,112,121,99,218,29,95,103,101,116,
+ 95,109,116,105,109,101,95,97,110,100,95,115,105,122,101,95,
+ 111,102,95,115,111,117,114,99,101,114,147,0,0,0,114,2,
+ 0,0,0,114,76,0,0,0,114,77,0,0,0,218,7,109,
+ 97,114,115,104,97,108,90,5,108,111,97,100,115,114,15,0,
+ 0,0,218,10,95,99,111,100,101,95,116,121,112,101,218,9,
+ 84,121,112,101,69,114,114,111,114,41,14,114,32,0,0,0,
+ 114,53,0,0,0,114,63,0,0,0,114,38,0,0,0,114,
+ 126,0,0,0,90,11,101,120,99,95,100,101,116,97,105,108,
+ 115,114,129,0,0,0,90,10,104,97,115,104,95,98,97,115,
+ 101,100,90,12,99,104,101,99,107,95,115,111,117,114,99,101,
+ 90,12,115,111,117,114,99,101,95,98,121,116,101,115,114,150,
+ 0,0,0,90,12,115,111,117,114,99,101,95,109,116,105,109,
+ 101,90,11,115,111,117,114,99,101,95,115,105,122,101,114,46,
+ 0,0,0,114,9,0,0,0,114,9,0,0,0,114,10,0,
+ 0,0,218,15,95,117,110,109,97,114,115,104,97,108,95,99,
+ 111,100,101,75,2,0,0,115,82,0,0,0,0,2,2,1,
+ 2,254,6,5,2,1,18,1,12,1,8,2,12,1,4,1,
+ 12,1,10,1,2,255,2,1,8,255,2,2,10,1,8,1,
+ 4,1,4,1,2,254,4,5,2,1,4,1,8,255,8,2,
+ 12,1,10,3,8,255,6,3,6,3,22,1,18,255,4,2,
+ 4,1,8,255,4,2,4,2,18,1,12,1,16,1,114,155,
+ 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,
+ 1,0,0,0,4,0,0,0,67,0,0,0,115,28,0,0,
+ 0,124,0,160,0,100,1,100,2,161,2,125,0,124,0,160,
+ 0,100,3,100,2,161,2,125,0,124,0,83,0,41,4,78,
+ 115,2,0,0,0,13,10,243,1,0,0,0,10,243,1,0,
+ 0,0,13,41,1,114,19,0,0,0,41,1,218,6,115,111,
+ 117,114,99,101,114,9,0,0,0,114,9,0,0,0,114,10,
+ 0,0,0,218,23,95,110,111,114,109,97,108,105,122,101,95,
+ 108,105,110,101,95,101,110,100,105,110,103,115,126,2,0,0,
+ 115,6,0,0,0,0,1,12,1,12,1,114,159,0,0,0,
+ 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,
+ 0,6,0,0,0,67,0,0,0,115,24,0,0,0,116,0,
+ 124,1,131,1,125,1,116,1,124,1,124,0,100,1,100,2,
+ 100,3,141,4,83,0,41,4,78,114,74,0,0,0,84,41,
+ 1,90,12,100,111,110,116,95,105,110,104,101,114,105,116,41,
+ 2,114,159,0,0,0,218,7,99,111,109,112,105,108,101,41,
+ 2,114,53,0,0,0,114,158,0,0,0,114,9,0,0,0,
+ 114,9,0,0,0,114,10,0,0,0,218,15,95,99,111,109,
+ 112,105,108,101,95,115,111,117,114,99,101,133,2,0,0,115,
+ 4,0,0,0,0,1,8,1,114,161,0,0,0,99,2,0,
+ 0,0,0,0,0,0,0,0,0,0,2,0,0,0,11,0,
+ 0,0,67,0,0,0,115,68,0,0,0,116,0,160,1,124,
+ 0,100,1,63,0,100,2,23,0,124,0,100,3,63,0,100,
+ 4,64,0,124,0,100,5,64,0,124,1,100,6,63,0,124,
+ 1,100,3,63,0,100,7,64,0,124,1,100,5,64,0,100,
+ 8,20,0,100,9,100,9,100,9,102,9,161,1,83,0,41,
+ 10,78,233,9,0,0,0,105,188,7,0,0,233,5,0,0,
+ 0,233,15,0,0,0,233,31,0,0,0,233,11,0,0,0,
+ 233,63,0,0,0,114,86,0,0,0,114,14,0,0,0,41,
+ 2,114,131,0,0,0,90,6,109,107,116,105,109,101,41,2,
+ 218,1,100,114,138,0,0,0,114,9,0,0,0,114,9,0,
+ 0,0,114,10,0,0,0,218,14,95,112,97,114,115,101,95,
+ 100,111,115,116,105,109,101,139,2,0,0,115,18,0,0,0,
+ 0,1,4,1,10,1,10,1,6,1,6,1,10,1,10,1,
+ 6,249,114,169,0,0,0,99,2,0,0,0,0,0,0,0,
+ 0,0,0,0,6,0,0,0,10,0,0,0,67,0,0,0,
+ 115,114,0,0,0,122,82,124,1,100,1,100,0,133,2,25,
+ 0,100,2,118,0,115,22,74,0,130,1,124,1,100,0,100,
+ 1,133,2,25,0,125,1,124,0,106,0,124,1,25,0,125,
+ 2,124,2,100,3,25,0,125,3,124,2,100,4,25,0,125,
+ 4,124,2,100,5,25,0,125,5,116,1,124,4,124,3,131,
+ 2,124,5,102,2,87,0,83,0,4,0,116,2,116,3,116,
+ 4,102,3,121,108,1,0,1,0,1,0,89,0,100,6,83,
+ 0,48,0,100,0,83,0,41,7,78,114,14,0,0,0,169,
+ 2,218,1,99,218,1,111,114,163,0,0,0,233,6,0,0,
+ 0,233,3,0,0,0,41,2,114,0,0,0,0,114,0,0,
+ 0,0,41,5,114,28,0,0,0,114,169,0,0,0,114,26,
+ 0,0,0,218,10,73,110,100,101,120,69,114,114,111,114,114,
+ 154,0,0,0,41,6,114,32,0,0,0,114,13,0,0,0,
+ 114,54,0,0,0,114,131,0,0,0,114,132,0,0,0,90,
+ 17,117,110,99,111,109,112,114,101,115,115,101,100,95,115,105,
+ 122,101,114,9,0,0,0,114,9,0,0,0,114,10,0,0,
+ 0,114,151,0,0,0,152,2,0,0,115,20,0,0,0,0,
+ 1,2,2,20,1,12,1,10,3,8,1,8,1,8,1,16,
+ 1,18,1,114,151,0,0,0,99,2,0,0,0,0,0,0,
+ 0,0,0,0,0,3,0,0,0,8,0,0,0,67,0,0,
+ 0,115,84,0,0,0,124,1,100,1,100,0,133,2,25,0,
+ 100,2,118,0,115,20,74,0,130,1,124,1,100,0,100,1,
+ 133,2,25,0,125,1,122,14,124,0,106,0,124,1,25,0,
+ 125,2,87,0,110,20,4,0,116,1,121,66,1,0,1,0,
+ 1,0,89,0,100,0,83,0,48,0,116,2,124,0,106,3,
+ 124,2,131,2,83,0,100,0,83,0,41,3,78,114,14,0,
+ 0,0,114,170,0,0,0,41,4,114,28,0,0,0,114,26,
+ 0,0,0,114,52,0,0,0,114,29,0,0,0,41,3,114,
+ 32,0,0,0,114,13,0,0,0,114,54,0,0,0,114,9,
+ 0,0,0,114,9,0,0,0,114,10,0,0,0,114,149,0,
+ 0,0,171,2,0,0,115,14,0,0,0,0,2,20,1,12,
+ 2,2,1,14,1,12,1,8,2,114,149,0,0,0,99,2,
+ 0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,9,
+ 0,0,0,67,0,0,0,115,196,0,0,0,116,0,124,0,
+ 124,1,131,2,125,2,116,1,68,0,93,158,92,3,125,3,
+ 125,4,125,5,124,2,124,3,23,0,125,6,116,2,106,3,
+ 100,1,124,0,106,4,116,5,124,6,100,2,100,3,141,5,
+ 1,0,122,14,124,0,106,6,124,6,25,0,125,7,87,0,
+ 110,18,4,0,116,7,121,86,1,0,1,0,1,0,89,0,
+ 113,14,48,0,124,7,100,4,25,0,125,8,116,8,124,0,
+ 106,4,124,7,131,2,125,9,124,4,114,130,116,9,124,0,
+ 124,8,124,6,124,1,124,9,131,5,125,10,110,10,116,10,
+ 124,8,124,9,131,2,125,10,124,10,100,0,117,0,114,150,
+ 113,14,124,7,100,4,25,0,125,8,124,10,124,5,124,8,
+ 102,3,2,0,1,0,83,0,113,14,116,11,100,5,124,1,
+ 155,2,157,2,124,1,100,6,141,2,130,1,100,0,83,0,
+ 41,7,78,122,13,116,114,121,105,110,103,32,123,125,123,125,
+ 123,125,114,86,0,0,0,41,1,90,9,118,101,114,98,111,
+ 115,105,116,121,114,0,0,0,0,114,57,0,0,0,114,58,
+ 0,0,0,41,12,114,36,0,0,0,114,89,0,0,0,114,
+ 76,0,0,0,114,77,0,0,0,114,29,0,0,0,114,20,
+ 0,0,0,114,28,0,0,0,114,26,0,0,0,114,52,0,
+ 0,0,114,155,0,0,0,114,161,0,0,0,114,3,0,0,
+ 0,41,11,114,32,0,0,0,114,38,0,0,0,114,13,0,
+ 0,0,114,90,0,0,0,114,91,0,0,0,114,47,0,0,
+ 0,114,63,0,0,0,114,54,0,0,0,114,40,0,0,0,
+ 114,126,0,0,0,114,46,0,0,0,114,9,0,0,0,114,
+ 9,0,0,0,114,10,0,0,0,114,44,0,0,0,186,2,
+ 0,0,115,36,0,0,0,0,1,10,1,14,1,8,1,22,
+ 1,2,1,14,1,12,1,6,2,8,1,12,1,4,1,18,
+ 2,10,1,8,3,2,1,8,1,16,2,114,44,0,0,0,
+ 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,2,0,0,0,64,0,0,0,115,60,0,0,0,101,0,
+ 90,1,100,0,90,2,100,1,90,3,100,2,90,4,100,3,
+ 100,4,132,0,90,5,100,5,100,6,132,0,90,6,100,7,
+ 100,8,132,0,90,7,100,9,100,10,132,0,90,8,100,11,
+ 100,12,132,0,90,9,100,13,83,0,41,14,114,80,0,0,
+ 0,122,165,80,114,105,118,97,116,101,32,99,108,97,115,115,
+ 32,117,115,101,100,32,116,111,32,115,117,112,112,111,114,116,
+ 32,90,105,112,73,109,112,111,114,116,46,103,101,116,95,114,
+ 101,115,111,117,114,99,101,95,114,101,97,100,101,114,40,41,
+ 46,10,10,32,32,32,32,84,104,105,115,32,99,108,97,115,
+ 115,32,105,115,32,97,108,108,111,119,101,100,32,116,111,32,
+ 114,101,102,101,114,101,110,99,101,32,97,108,108,32,116,104,
+ 101,32,105,110,110,97,114,100,115,32,97,110,100,32,112,114,
+ 105,118,97,116,101,32,112,97,114,116,115,32,111,102,10,32,
+ 32,32,32,116,104,101,32,122,105,112,105,109,112,111,114,116,
+ 101,114,46,10,32,32,32,32,70,99,3,0,0,0,0,0,
+ 0,0,0,0,0,0,3,0,0,0,2,0,0,0,67,0,
+ 0,0,115,16,0,0,0,124,1,124,0,95,0,124,2,124,
+ 0,95,1,100,0,83,0,114,88,0,0,0,41,2,114,4,
+ 0,0,0,114,38,0,0,0,41,3,114,32,0,0,0,114,
+ 4,0,0,0,114,38,0,0,0,114,9,0,0,0,114,9,
+ 0,0,0,114,10,0,0,0,114,34,0,0,0,220,2,0,
+ 0,115,4,0,0,0,0,1,6,1,122,33,95,90,105,112,
+ 73,109,112,111,114,116,82,101,115,111,117,114,99,101,82,101,
+ 97,100,101,114,46,95,95,105,110,105,116,95,95,99,2,0,
+ 0,0,0,0,0,0,0,0,0,0,5,0,0,0,8,0,
+ 0,0,67,0,0,0,115,90,0,0,0,124,0,106,0,160,
+ 1,100,1,100,2,161,2,125,2,124,2,155,0,100,2,124,
+ 1,155,0,157,3,125,3,100,3,100,4,108,2,109,3,125,
+ 4,1,0,122,18,124,4,124,0,106,4,160,5,124,3,161,
+ 1,131,1,87,0,83,0,4,0,116,6,121,84,1,0,1,
+ 0,1,0,116,7,124,3,131,1,130,1,89,0,110,2,48,
+ 0,100,0,83,0,41,5,78,114,85,0,0,0,114,109,0,
+ 0,0,114,0,0,0,0,41,1,218,7,66,121,116,101,115,
+ 73,79,41,8,114,38,0,0,0,114,19,0,0,0,90,2,
+ 105,111,114,176,0,0,0,114,4,0,0,0,114,55,0,0,
+ 0,114,22,0,0,0,218,17,70,105,108,101,78,111,116,70,
+ 111,117,110,100,69,114,114,111,114,41,5,114,32,0,0,0,
+ 218,8,114,101,115,111,117,114,99,101,218,16,102,117,108,108,
+ 110,97,109,101,95,97,115,95,112,97,116,104,114,13,0,0,
+ 0,114,176,0,0,0,114,9,0,0,0,114,9,0,0,0,
+ 114,10,0,0,0,218,13,111,112,101,110,95,114,101,115,111,
+ 117,114,99,101,224,2,0,0,115,14,0,0,0,0,1,14,
+ 1,14,1,12,1,2,1,18,1,12,1,122,38,95,90,105,
+ 112,73,109,112,111,114,116,82,101,115,111,117,114,99,101,82,
+ 101,97,100,101,114,46,111,112,101,110,95,114,101,115,111,117,
+ 114,99,101,99,2,0,0,0,0,0,0,0,0,0,0,0,
+ 2,0,0,0,1,0,0,0,67,0,0,0,115,8,0,0,
+ 0,116,0,130,1,100,0,83,0,114,88,0,0,0,41,1,
+ 114,177,0,0,0,41,2,114,32,0,0,0,114,178,0,0,
+ 0,114,9,0,0,0,114,9,0,0,0,114,10,0,0,0,
+ 218,13,114,101,115,111,117,114,99,101,95,112,97,116,104,233,
+ 2,0,0,115,2,0,0,0,0,4,122,38,95,90,105,112,
+ 73,109,112,111,114,116,82,101,115,111,117,114,99,101,82,101,
+ 97,100,101,114,46,114,101,115,111,117,114,99,101,95,112,97,
+ 116,104,99,2,0,0,0,0,0,0,0,0,0,0,0,4,
+ 0,0,0,8,0,0,0,67,0,0,0,115,70,0,0,0,
+ 124,0,106,0,160,1,100,1,100,2,161,2,125,2,124,2,
+ 155,0,100,2,124,1,155,0,157,3,125,3,122,16,124,0,
+ 106,2,160,3,124,3,161,1,1,0,87,0,110,20,4,0,
+ 116,4,121,64,1,0,1,0,1,0,89,0,100,3,83,0,
+ 48,0,100,4,83,0,41,5,78,114,85,0,0,0,114,109,
+ 0,0,0,70,84,41,5,114,38,0,0,0,114,19,0,0,
+ 0,114,4,0,0,0,114,55,0,0,0,114,22,0,0,0,
+ 41,4,114,32,0,0,0,114,59,0,0,0,114,179,0,0,
+ 0,114,13,0,0,0,114,9,0,0,0,114,9,0,0,0,
+ 114,10,0,0,0,218,11,105,115,95,114,101,115,111,117,114,
+ 99,101,239,2,0,0,115,14,0,0,0,0,3,14,1,14,
+ 1,2,1,16,1,12,1,8,1,122,36,95,90,105,112,73,
+ 109,112,111,114,116,82,101,115,111,117,114,99,101,82,101,97,
+ 100,101,114,46,105,115,95,114,101,115,111,117,114,99,101,99,
+ 1,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,
+ 9,0,0,0,99,0,0,0,115,184,0,0,0,100,1,100,
+ 2,108,0,109,1,125,1,1,0,124,1,124,0,106,2,160,
+ 3,124,0,106,4,161,1,131,1,125,2,124,2,160,5,124,
+ 0,106,2,106,6,161,1,125,3,124,3,106,7,100,3,107,
+ 2,115,58,74,0,130,1,124,3,106,8,125,4,116,9,131,
+ 0,125,5,124,0,106,2,106,10,68,0,93,100,125,6,122,
+ 18,124,1,124,6,131,1,160,5,124,4,161,1,125,7,87,
+ 0,110,22,4,0,116,11,121,122,1,0,1,0,1,0,89,
+ 0,113,78,89,0,110,2,48,0,124,7,106,8,106,7,125,
+ 8,116,12,124,8,131,1,100,1,107,2,114,154,124,7,106,
+ 7,86,0,1,0,113,78,124,8,124,5,118,1,114,78,124,
+ 5,160,13,124,8,161,1,1,0,124,8,86,0,1,0,113,
+ 78,100,0,83,0,41,4,78,114,0,0,0,0,41,1,218,
+ 4,80,97,116,104,114,60,0,0,0,41,14,90,7,112,97,
+ 116,104,108,105,98,114,183,0,0,0,114,4,0,0,0,114,
+ 56,0,0,0,114,38,0,0,0,90,11,114,101,108,97,116,
+ 105,118,101,95,116,111,114,29,0,0,0,114,59,0,0,0,
+ 90,6,112,97,114,101,110,116,218,3,115,101,116,114,28,0,
+ 0,0,114,23,0,0,0,114,51,0,0,0,218,3,97,100,
+ 100,41,9,114,32,0,0,0,114,183,0,0,0,90,13,102,
+ 117,108,108,110,97,109,101,95,112,97,116,104,90,13,114,101,
+ 108,97,116,105,118,101,95,112,97,116,104,90,12,112,97,99,
+ 107,97,103,101,95,112,97,116,104,90,12,115,117,98,100,105,
+ 114,115,95,115,101,101,110,218,8,102,105,108,101,110,97,109,
+ 101,90,8,114,101,108,97,116,105,118,101,90,11,112,97,114,
+ 101,110,116,95,110,97,109,101,114,9,0,0,0,114,9,0,
+ 0,0,114,10,0,0,0,218,8,99,111,110,116,101,110,116,
+ 115,250,2,0,0,115,34,0,0,0,0,8,12,1,18,1,
+ 14,3,14,1,6,1,6,1,12,1,2,1,18,1,12,1,
+ 10,5,8,1,12,1,10,1,8,1,10,1,122,33,95,90,
+ 105,112,73,109,112,111,114,116,82,101,115,111,117,114,99,101,
+ 82,101,97,100,101,114,46,99,111,110,116,101,110,116,115,78,
+ 41,10,114,6,0,0,0,114,7,0,0,0,114,8,0,0,
+ 0,114,84,0,0,0,114,81,0,0,0,114,34,0,0,0,
+ 114,180,0,0,0,114,181,0,0,0,114,182,0,0,0,114,
+ 187,0,0,0,114,9,0,0,0,114,9,0,0,0,114,9,
+ 0,0,0,114,10,0,0,0,114,80,0,0,0,212,2,0,
+ 0,115,14,0,0,0,8,1,4,5,4,2,8,4,8,9,
+ 8,6,8,11,114,80,0,0,0,41,45,114,84,0,0,0,
+ 90,26,95,102,114,111,122,101,110,95,105,109,112,111,114,116,
+ 108,105,98,95,101,120,116,101,114,110,97,108,114,21,0,0,
+ 0,114,1,0,0,0,114,2,0,0,0,90,17,95,102,114,
+ 111,122,101,110,95,105,109,112,111,114,116,108,105,98,114,76,
+ 0,0,0,114,148,0,0,0,114,110,0,0,0,114,152,0,
+ 0,0,114,67,0,0,0,114,131,0,0,0,90,7,95,95,
+ 97,108,108,95,95,114,20,0,0,0,90,15,112,97,116,104,
+ 95,115,101,112,97,114,97,116,111,114,115,114,18,0,0,0,
+ 114,75,0,0,0,114,3,0,0,0,114,25,0,0,0,218,
+ 4,116,121,112,101,114,70,0,0,0,114,113,0,0,0,114,
+ 115,0,0,0,114,117,0,0,0,114,4,0,0,0,114,89,
+ 0,0,0,114,36,0,0,0,114,37,0,0,0,114,35,0,
+ 0,0,114,27,0,0,0,114,122,0,0,0,114,142,0,0,
+ 0,114,144,0,0,0,114,52,0,0,0,114,147,0,0,0,
+ 114,155,0,0,0,218,8,95,95,99,111,100,101,95,95,114,
+ 153,0,0,0,114,159,0,0,0,114,161,0,0,0,114,169,
+ 0,0,0,114,151,0,0,0,114,149,0,0,0,114,44,0,
+ 0,0,114,80,0,0,0,114,9,0,0,0,114,9,0,0,
+ 0,114,9,0,0,0,114,10,0,0,0,218,8,60,109,111,
+ 100,117,108,101,62,1,0,0,0,115,88,0,0,0,4,16,
+ 8,1,16,1,8,1,8,1,8,1,8,1,8,1,8,2,
+ 8,3,6,1,14,3,16,4,4,2,8,2,4,1,4,1,
+ 4,2,14,127,0,127,0,1,12,1,12,1,2,1,2,252,
+ 4,9,8,4,8,9,8,31,8,126,2,254,2,29,4,5,
+ 8,21,8,46,8,10,8,46,10,5,8,7,8,6,8,13,
+ 8,19,8,15,8,26,
+};
diff --git a/contrib/tools/python3/src/Python/initconfig.c b/contrib/tools/python3/src/Python/initconfig.c
new file mode 100644
index 00000000000..9c109cef2c1
--- /dev/null
+++ b/contrib/tools/python3/src/Python/initconfig.c
@@ -0,0 +1,2765 @@
+#include "Python.h"
+#include "pycore_fileutils.h" // _Py_HasFileSystemDefaultEncodeErrors
+#include "pycore_getopt.h" // _PyOS_GetOpt()
+#include "pycore_initconfig.h" // _PyStatus_OK()
+#include "pycore_interp.h" // _PyInterpreterState.runtime
+#include "pycore_pathconfig.h" // _Py_path_config
+#include "pycore_pyerrors.h" // _PyErr_Fetch()
+#include "pycore_pylifecycle.h" // _Py_PreInitializeFromConfig()
+#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
+#include "pycore_pystate.h" // _PyThreadState_GET()
+
+#include "osdefs.h" // DELIM
+#include <locale.h> // setlocale()
+#ifdef HAVE_LANGINFO_H
+# include <langinfo.h> // nl_langinfo(CODESET)
+#endif
+#if defined(MS_WINDOWS) || defined(__CYGWIN__)
+# include <windows.h> // GetACP()
+# ifdef HAVE_IO_H
+# include <io.h>
+# endif
+# ifdef HAVE_FCNTL_H
+# include <fcntl.h> // O_BINARY
+# endif
+#endif
+
+#ifndef PLATLIBDIR
+# error "PLATLIBDIR macro must be defined"
+#endif
+
+
+/* --- Command line options --------------------------------------- */
+
+/* Short usage message (with %s for argv0) */
+static const char usage_line[] =
+"usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
+
+/* Long usage message, split into parts < 512 bytes */
+static const char usage_1[] = "\
+Options and arguments (and corresponding environment variables):\n\
+-b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
+ and comparing bytes/bytearray with str. (-bb: issue errors)\n\
+-B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\
+-c cmd : program passed in as string (terminates option list)\n\
+-d : turn on parser debugging output (for experts only, only works on\n\
+ debug builds); also PYTHONDEBUG=x\n\
+-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
+-h : print this help message and exit (also --help)\n\
+";
+static const char usage_2[] = "\
+-i : inspect interactively after running script; forces a prompt even\n\
+ if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
+-I : isolate Python from the user's environment (implies -E and -s)\n\
+-m mod : run library module as a script (terminates option list)\n\
+-O : remove assert and __debug__-dependent statements; add .opt-1 before\n\
+ .pyc extension; also PYTHONOPTIMIZE=x\n\
+-OO : do -O changes and also discard docstrings; add .opt-2 before\n\
+ .pyc extension\n\
+-q : don't print version and copyright messages on interactive startup\n\
+-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
+-S : don't imply 'import site' on initialization\n\
+";
+static const char usage_3[] = "\
+-u : force the stdout and stderr streams to be unbuffered;\n\
+ this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\
+-v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
+ can be supplied multiple times to increase verbosity\n\
+-V : print the Python version number and exit (also --version)\n\
+ when given twice, print more information about the build\n\
+-W arg : warning control; arg is action:message:category:module:lineno\n\
+ also PYTHONWARNINGS=arg\n\
+-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
+-X opt : set implementation-specific option. The following options are available:\n\
+\n\
+ -X faulthandler: enable faulthandler\n\
+ -X oldparser: enable the traditional LL(1) parser; also PYTHONOLDPARSER\n\
+ -X showrefcount: output the total reference count and number of used\n\
+ memory blocks when the program finishes or after each statement in the\n\
+ interactive interpreter. This only works on debug builds\n\
+ -X tracemalloc: start tracing Python memory allocations using the\n\
+ tracemalloc module. By default, only the most recent frame is stored in a\n\
+ traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\
+ traceback limit of NFRAME frames\n\
+ -X importtime: show how long each import takes. It shows module name,\n\
+ cumulative time (including nested imports) and self time (excluding\n\
+ nested imports). Note that its output may be broken in multi-threaded\n\
+ application. Typical usage is python3 -X importtime -c 'import asyncio'\n\
+ -X dev: enable CPython's \"development mode\", introducing additional runtime\n\
+ checks which are too expensive to be enabled by default. Effect of the\n\
+ developer mode:\n\
+ * Add default warning filter, as -W default\n\
+ * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function\n\
+ * Enable the faulthandler module to dump the Python traceback on a crash\n\
+ * Enable asyncio debug mode\n\
+ * Set the dev_mode attribute of sys.flags to True\n\
+ * io.IOBase destructor logs close() exceptions\n\
+ -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\
+ locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\
+ otherwise activate automatically)\n\
+ -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\
+ given directory instead of to the code tree\n\
+\n\
+--check-hash-based-pycs always|default|never:\n\
+ control how Python invalidates hash-based .pyc files\n\
+";
+static const char usage_4[] = "\
+file : program read from script file\n\
+- : program read from stdin (default; interactive mode if a tty)\n\
+arg ...: arguments passed to program in sys.argv[1:]\n\n\
+Other environment variables:\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\
+";
+static const char usage_5[] =
+"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
+" The default module search path uses %s.\n"
+"PYTHONPLATLIBDIR : override sys.platlibdir.\n"
+"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
+"PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n"
+"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
+"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
+static const char usage_6[] =
+"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 set to an\n"
+" integer in the range [0,4294967295] to get hash values with a\n"
+" predictable seed.\n"
+"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
+" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
+" hooks.\n"
+"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
+" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
+" locale coercion and locale compatibility warnings 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 choice.\n"
+"PYTHONDEVMODE: enable the development mode.\n"
+"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n";
+
+#if defined(MS_WINDOWS)
+# define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
+#else
+# define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
+#endif
+
+
+/* --- Global configuration variables ----------------------------- */
+
+/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
+ stdin and stdout error handler to "surrogateescape". */
+int Py_UTF8Mode = 0;
+int Py_DebugFlag = 0; /* Needed by parser.c */
+int Py_VerboseFlag = 0; /* Needed by import.c */
+int Py_QuietFlag = 0; /* Needed by sysmodule.c */
+int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
+int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
+int Py_OptimizeFlag = 0; /* Needed by compile.c */
+int Py_NoSiteFlag = 0; /* Suppress 'import site' */
+int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
+int Py_FrozenFlag = 1; /* Needed by getpath.c */
+int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
+int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
+int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
+int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
+int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
+int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
+#ifdef MS_WINDOWS
+int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
+int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
+#endif
+
+
+static PyObject *
+_Py_GetGlobalVariablesAsDict(void)
+{
+ PyObject *dict, *obj;
+
+ dict = PyDict_New();
+ if (dict == NULL) {
+ return NULL;
+ }
+
+#define SET_ITEM(KEY, EXPR) \
+ do { \
+ obj = (EXPR); \
+ if (obj == NULL) { \
+ return NULL; \
+ } \
+ int res = PyDict_SetItemString(dict, (KEY), obj); \
+ Py_DECREF(obj); \
+ if (res < 0) { \
+ goto fail; \
+ } \
+ } while (0)
+#define SET_ITEM_INT(VAR) \
+ SET_ITEM(#VAR, PyLong_FromLong(VAR))
+#define FROM_STRING(STR) \
+ ((STR != NULL) ? \
+ PyUnicode_FromString(STR) \
+ : (Py_INCREF(Py_None), Py_None))
+#define SET_ITEM_STR(VAR) \
+ SET_ITEM(#VAR, FROM_STRING(VAR))
+
+ SET_ITEM_STR(Py_FileSystemDefaultEncoding);
+ SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
+ SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
+ SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors);
+
+ SET_ITEM_INT(Py_UTF8Mode);
+ SET_ITEM_INT(Py_DebugFlag);
+ SET_ITEM_INT(Py_VerboseFlag);
+ SET_ITEM_INT(Py_QuietFlag);
+ SET_ITEM_INT(Py_InteractiveFlag);
+ SET_ITEM_INT(Py_InspectFlag);
+
+ SET_ITEM_INT(Py_OptimizeFlag);
+ SET_ITEM_INT(Py_NoSiteFlag);
+ SET_ITEM_INT(Py_BytesWarningFlag);
+ SET_ITEM_INT(Py_FrozenFlag);
+ SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
+ SET_ITEM_INT(Py_DontWriteBytecodeFlag);
+ SET_ITEM_INT(Py_NoUserSiteDirectory);
+ SET_ITEM_INT(Py_UnbufferedStdioFlag);
+ SET_ITEM_INT(Py_HashRandomizationFlag);
+ SET_ITEM_INT(Py_IsolatedFlag);
+
+#ifdef MS_WINDOWS
+ SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
+ SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
+#endif
+
+ return dict;
+
+fail:
+ Py_DECREF(dict);
+ return NULL;
+
+#undef FROM_STRING
+#undef SET_ITEM
+#undef SET_ITEM_INT
+#undef SET_ITEM_STR
+}
+
+
+/* --- PyStatus ----------------------------------------------- */
+
+PyStatus PyStatus_Ok(void)
+{ return _PyStatus_OK(); }
+
+PyStatus PyStatus_Error(const char *err_msg)
+{
+ return (PyStatus){._type = _PyStatus_TYPE_ERROR,
+ .err_msg = err_msg};
+}
+
+PyStatus PyStatus_NoMemory(void)
+{ return PyStatus_Error("memory allocation failed"); }
+
+PyStatus PyStatus_Exit(int exitcode)
+{ return _PyStatus_EXIT(exitcode); }
+
+
+int PyStatus_IsError(PyStatus status)
+{ return _PyStatus_IS_ERROR(status); }
+
+int PyStatus_IsExit(PyStatus status)
+{ return _PyStatus_IS_EXIT(status); }
+
+int PyStatus_Exception(PyStatus status)
+{ return _PyStatus_EXCEPTION(status); }
+
+
+/* --- PyWideStringList ------------------------------------------------ */
+
+#ifndef NDEBUG
+int
+_PyWideStringList_CheckConsistency(const PyWideStringList *list)
+{
+ assert(list->length >= 0);
+ if (list->length != 0) {
+ assert(list->items != NULL);
+ }
+ for (Py_ssize_t i = 0; i < list->length; i++) {
+ assert(list->items[i] != NULL);
+ }
+ return 1;
+}
+#endif /* Py_DEBUG */
+
+
+void
+_PyWideStringList_Clear(PyWideStringList *list)
+{
+ assert(_PyWideStringList_CheckConsistency(list));
+ for (Py_ssize_t i=0; i < list->length; i++) {
+ PyMem_RawFree(list->items[i]);
+ }
+ PyMem_RawFree(list->items);
+ list->length = 0;
+ list->items = NULL;
+}
+
+
+int
+_PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
+{
+ assert(_PyWideStringList_CheckConsistency(list));
+ assert(_PyWideStringList_CheckConsistency(list2));
+
+ if (list2->length == 0) {
+ _PyWideStringList_Clear(list);
+ return 0;
+ }
+
+ PyWideStringList copy = _PyWideStringList_INIT;
+
+ size_t size = list2->length * sizeof(list2->items[0]);
+ copy.items = PyMem_RawMalloc(size);
+ if (copy.items == NULL) {
+ return -1;
+ }
+
+ for (Py_ssize_t i=0; i < list2->length; i++) {
+ wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
+ if (item == NULL) {
+ _PyWideStringList_Clear(&copy);
+ return -1;
+ }
+ copy.items[i] = item;
+ copy.length = i + 1;
+ }
+
+ _PyWideStringList_Clear(list);
+ *list = copy;
+ return 0;
+}
+
+
+PyStatus
+PyWideStringList_Insert(PyWideStringList *list,
+ Py_ssize_t index, const wchar_t *item)
+{
+ Py_ssize_t len = list->length;
+ if (len == PY_SSIZE_T_MAX) {
+ /* length+1 would overflow */
+ return _PyStatus_NO_MEMORY();
+ }
+ if (index < 0) {
+ return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0");
+ }
+ if (index > len) {
+ index = len;
+ }
+
+ wchar_t *item2 = _PyMem_RawWcsdup(item);
+ if (item2 == NULL) {
+ return _PyStatus_NO_MEMORY();
+ }
+
+ size_t size = (len + 1) * sizeof(list->items[0]);
+ wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
+ if (items2 == NULL) {
+ PyMem_RawFree(item2);
+ return _PyStatus_NO_MEMORY();
+ }
+
+ if (index < len) {
+ memmove(&items2[index + 1],
+ &items2[index],
+ (len - index) * sizeof(items2[0]));
+ }
+
+ items2[index] = item2;
+ list->items = items2;
+ list->length++;
+ return _PyStatus_OK();
+}
+
+
+PyStatus
+PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
+{
+ return PyWideStringList_Insert(list, list->length, item);
+}
+
+
+PyStatus
+_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
+{
+ for (Py_ssize_t i = 0; i < list2->length; i++) {
+ PyStatus status = PyWideStringList_Append(list, list2->items[i]);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+ return _PyStatus_OK();
+}
+
+
+static int
+_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
+{
+ for (Py_ssize_t i = 0; i < list->length; i++) {
+ if (wcscmp(list->items[i], item) == 0) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+PyObject*
+_PyWideStringList_AsList(const PyWideStringList *list)
+{
+ assert(_PyWideStringList_CheckConsistency(list));
+
+ PyObject *pylist = PyList_New(list->length);
+ if (pylist == NULL) {
+ return NULL;
+ }
+
+ for (Py_ssize_t i = 0; i < list->length; i++) {
+ PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
+ if (item == NULL) {
+ Py_DECREF(pylist);
+ return NULL;
+ }
+ PyList_SET_ITEM(pylist, i, item);
+ }
+ return pylist;
+}
+
+
+/* --- Py_SetStandardStreamEncoding() ----------------------------- */
+
+/* Helper to allow an embedding application to override the normal
+ * mechanism that attempts to figure out an appropriate IO encoding
+ */
+
+static char *_Py_StandardStreamEncoding = NULL;
+static char *_Py_StandardStreamErrors = NULL;
+
+int
+Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
+{
+ if (Py_IsInitialized()) {
+ /* This is too late to have any effect */
+ return -1;
+ }
+
+ int res = 0;
+
+ /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
+ but Py_Initialize() can change the allocator. Use a known allocator
+ to be able to release the memory later. */
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
+ * initialised yet.
+ *
+ * However, the raw memory allocators are initialised appropriately
+ * as C static variables, so _PyMem_RawStrdup is OK even though
+ * Py_Initialize hasn't been called yet.
+ */
+ if (encoding) {
+ PyMem_RawFree(_Py_StandardStreamEncoding);
+ _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
+ if (!_Py_StandardStreamEncoding) {
+ res = -2;
+ goto done;
+ }
+ }
+ if (errors) {
+ PyMem_RawFree(_Py_StandardStreamErrors);
+ _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
+ if (!_Py_StandardStreamErrors) {
+ PyMem_RawFree(_Py_StandardStreamEncoding);
+ _Py_StandardStreamEncoding = NULL;
+ res = -3;
+ goto done;
+ }
+ }
+#ifdef MS_WINDOWS
+ if (_Py_StandardStreamEncoding) {
+ /* Overriding the stream encoding implies legacy streams */
+ Py_LegacyWindowsStdioFlag = 1;
+ }
+#endif
+
+done:
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ return res;
+}
+
+
+void
+_Py_ClearStandardStreamEncoding(void)
+{
+ /* Use the same allocator than Py_SetStandardStreamEncoding() */
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ /* We won't need them anymore. */
+ if (_Py_StandardStreamEncoding) {
+ PyMem_RawFree(_Py_StandardStreamEncoding);
+ _Py_StandardStreamEncoding = NULL;
+ }
+ if (_Py_StandardStreamErrors) {
+ PyMem_RawFree(_Py_StandardStreamErrors);
+ _Py_StandardStreamErrors = NULL;
+ }
+
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+}
+
+
+/* --- Py_GetArgcArgv() ------------------------------------------- */
+
+/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
+static PyWideStringList orig_argv = {.length = 0, .items = NULL};
+
+
+void
+_Py_ClearArgcArgv(void)
+{
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ _PyWideStringList_Clear(&orig_argv);
+
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+}
+
+
+static int
+_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
+{
+ const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv};
+ int res;
+
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ res = _PyWideStringList_Copy(&orig_argv, &argv_list);
+
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+ return res;
+}
+
+
+void
+Py_GetArgcArgv(int *argc, wchar_t ***argv)
+{
+ *argc = (int)orig_argv.length;
+ *argv = orig_argv.items;
+}
+
+
+void
+Py_InitArgcArgv(int argc, wchar_t **argv)
+{
+ _Py_SetArgcArgv((Py_ssize_t)argc, argv);
+}
+
+/* --- PyConfig ---------------------------------------------- */
+
+#define DECODE_LOCALE_ERR(NAME, LEN) \
+ (((LEN) == -2) \
+ ? _PyStatus_ERR("cannot decode " NAME) \
+ : _PyStatus_NO_MEMORY())
+
+
+/* Free memory allocated in config, but don't clear all attributes */
+void
+PyConfig_Clear(PyConfig *config)
+{
+#define CLEAR(ATTR) \
+ do { \
+ PyMem_RawFree(ATTR); \
+ ATTR = NULL; \
+ } while (0)
+
+ CLEAR(config->pycache_prefix);
+ CLEAR(config->pythonpath_env);
+ CLEAR(config->home);
+ CLEAR(config->program_name);
+
+ _PyWideStringList_Clear(&config->argv);
+ _PyWideStringList_Clear(&config->warnoptions);
+ _PyWideStringList_Clear(&config->xoptions);
+ _PyWideStringList_Clear(&config->module_search_paths);
+ config->module_search_paths_set = 0;
+
+ CLEAR(config->executable);
+ CLEAR(config->base_executable);
+ CLEAR(config->prefix);
+ CLEAR(config->base_prefix);
+ CLEAR(config->exec_prefix);
+ CLEAR(config->base_exec_prefix);
+ CLEAR(config->platlibdir);
+
+ CLEAR(config->filesystem_encoding);
+ CLEAR(config->filesystem_errors);
+ CLEAR(config->stdio_encoding);
+ CLEAR(config->stdio_errors);
+ CLEAR(config->run_command);
+ CLEAR(config->run_module);
+ CLEAR(config->run_filename);
+ CLEAR(config->check_hash_pycs_mode);
+
+ _PyWideStringList_Clear(&config->_orig_argv);
+#undef CLEAR
+}
+
+
+void
+_PyConfig_InitCompatConfig(PyConfig *config)
+{
+ memset(config, 0, sizeof(*config));
+
+ config->_config_init = (int)_PyConfig_INIT_COMPAT;
+ config->isolated = -1;
+ config->use_environment = -1;
+ config->dev_mode = -1;
+ config->install_signal_handlers = 1;
+ config->use_hash_seed = -1;
+ config->faulthandler = -1;
+ config->tracemalloc = -1;
+ config->module_search_paths_set = 0;
+ config->parse_argv = 0;
+ config->site_import = -1;
+ config->bytes_warning = -1;
+ config->inspect = -1;
+ config->interactive = -1;
+ config->optimization_level = -1;
+ config->parser_debug= -1;
+ config->write_bytecode = -1;
+ config->verbose = -1;
+ config->quiet = -1;
+ config->user_site_directory = -1;
+ config->configure_c_stdio = 0;
+ config->buffered_stdio = -1;
+ config->_install_importlib = 1;
+ config->check_hash_pycs_mode = NULL;
+ config->pathconfig_warnings = -1;
+ config->_init_main = 1;
+ config->_isolated_interpreter = 0;
+#ifdef MS_WINDOWS
+ config->legacy_windows_stdio = -1;
+#endif
+ config->_use_peg_parser = 1;
+}
+
+
+static void
+config_init_defaults(PyConfig *config)
+{
+ _PyConfig_InitCompatConfig(config);
+
+ config->isolated = 0;
+ config->use_environment = 1;
+ config->site_import = 1;
+ config->bytes_warning = 0;
+ config->inspect = 0;
+ config->interactive = 0;
+ config->optimization_level = 0;
+ config->parser_debug= 0;
+ config->write_bytecode = 1;
+ config->verbose = 0;
+ config->quiet = 0;
+ config->user_site_directory = 1;
+ config->buffered_stdio = 1;
+ config->pathconfig_warnings = 1;
+#ifdef MS_WINDOWS
+ config->legacy_windows_stdio = 0;
+#endif
+}
+
+
+void
+PyConfig_InitPythonConfig(PyConfig *config)
+{
+ config_init_defaults(config);
+
+ config->_config_init = (int)_PyConfig_INIT_PYTHON;
+ config->configure_c_stdio = 1;
+ config->parse_argv = 1;
+}
+
+
+void
+PyConfig_InitIsolatedConfig(PyConfig *config)
+{
+ config_init_defaults(config);
+
+ config->_config_init = (int)_PyConfig_INIT_ISOLATED;
+ config->isolated = 1;
+ config->use_environment = 0;
+ config->user_site_directory = 0;
+ config->dev_mode = 0;
+ config->install_signal_handlers = 0;
+ config->use_hash_seed = 0;
+ config->faulthandler = 0;
+ config->tracemalloc = 0;
+ config->pathconfig_warnings = 0;
+#ifdef MS_WINDOWS
+ config->legacy_windows_stdio = 0;
+#endif
+}
+
+
+/* Copy str into *config_str (duplicate the string) */
+PyStatus
+PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
+{
+ PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ wchar_t *str2;
+ if (str != NULL) {
+ str2 = _PyMem_RawWcsdup(str);
+ if (str2 == NULL) {
+ return _PyStatus_NO_MEMORY();
+ }
+ }
+ else {
+ str2 = NULL;
+ }
+ PyMem_RawFree(*config_str);
+ *config_str = str2;
+ return _PyStatus_OK();
+}
+
+
+static PyStatus
+config_set_bytes_string(PyConfig *config, wchar_t **config_str,
+ const char *str, const char *decode_err_msg)
+{
+ PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ wchar_t *str2;
+ if (str != NULL) {
+ size_t len;
+ str2 = Py_DecodeLocale(str, &len);
+ if (str2 == NULL) {
+ if (len == (size_t)-2) {
+ return _PyStatus_ERR(decode_err_msg);
+ }
+ else {
+ return _PyStatus_NO_MEMORY();
+ }
+ }
+ }
+ else {
+ str2 = NULL;
+ }
+ PyMem_RawFree(*config_str);
+ *config_str = str2;
+ return _PyStatus_OK();
+}
+
+
+#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
+ config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
+
+
+/* Decode str using Py_DecodeLocale() and set the result into *config_str.
+ Pre-initialize Python if needed to ensure that encodings are properly
+ configured. */
+PyStatus
+PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
+ const char *str)
+{
+ return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
+}
+
+
+PyStatus
+_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
+{
+ PyStatus status;
+
+ PyConfig_Clear(config);
+
+#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
+#define COPY_WSTR_ATTR(ATTR) \
+ do { \
+ status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
+ if (_PyStatus_EXCEPTION(status)) { \
+ return status; \
+ } \
+ } while (0)
+#define COPY_WSTRLIST(LIST) \
+ do { \
+ if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
+ return _PyStatus_NO_MEMORY(); \
+ } \
+ } while (0)
+
+ COPY_ATTR(_config_init);
+ COPY_ATTR(isolated);
+ COPY_ATTR(use_environment);
+ COPY_ATTR(dev_mode);
+ COPY_ATTR(_use_peg_parser);
+ COPY_ATTR(install_signal_handlers);
+ COPY_ATTR(use_hash_seed);
+ COPY_ATTR(hash_seed);
+ COPY_ATTR(_install_importlib);
+ COPY_ATTR(faulthandler);
+ COPY_ATTR(tracemalloc);
+ COPY_ATTR(import_time);
+ COPY_ATTR(show_ref_count);
+ COPY_ATTR(dump_refs);
+ COPY_ATTR(malloc_stats);
+
+ COPY_WSTR_ATTR(pycache_prefix);
+ COPY_WSTR_ATTR(pythonpath_env);
+ COPY_WSTR_ATTR(home);
+ COPY_WSTR_ATTR(program_name);
+
+ COPY_ATTR(parse_argv);
+ COPY_WSTRLIST(argv);
+ COPY_WSTRLIST(warnoptions);
+ COPY_WSTRLIST(xoptions);
+ COPY_WSTRLIST(module_search_paths);
+ COPY_ATTR(module_search_paths_set);
+
+ COPY_WSTR_ATTR(executable);
+ COPY_WSTR_ATTR(base_executable);
+ COPY_WSTR_ATTR(prefix);
+ COPY_WSTR_ATTR(base_prefix);
+ COPY_WSTR_ATTR(exec_prefix);
+ COPY_WSTR_ATTR(base_exec_prefix);
+ COPY_WSTR_ATTR(platlibdir);
+
+ COPY_ATTR(site_import);
+ COPY_ATTR(bytes_warning);
+ COPY_ATTR(inspect);
+ COPY_ATTR(interactive);
+ COPY_ATTR(optimization_level);
+ COPY_ATTR(parser_debug);
+ COPY_ATTR(write_bytecode);
+ COPY_ATTR(verbose);
+ COPY_ATTR(quiet);
+ COPY_ATTR(user_site_directory);
+ COPY_ATTR(configure_c_stdio);
+ COPY_ATTR(buffered_stdio);
+ COPY_WSTR_ATTR(filesystem_encoding);
+ COPY_WSTR_ATTR(filesystem_errors);
+ COPY_WSTR_ATTR(stdio_encoding);
+ COPY_WSTR_ATTR(stdio_errors);
+#ifdef MS_WINDOWS
+ COPY_ATTR(legacy_windows_stdio);
+#endif
+ COPY_ATTR(skip_source_first_line);
+ COPY_WSTR_ATTR(run_command);
+ COPY_WSTR_ATTR(run_module);
+ COPY_WSTR_ATTR(run_filename);
+ COPY_WSTR_ATTR(check_hash_pycs_mode);
+ COPY_ATTR(pathconfig_warnings);
+ COPY_ATTR(_init_main);
+ COPY_ATTR(_isolated_interpreter);
+ COPY_WSTRLIST(_orig_argv);
+
+#undef COPY_ATTR
+#undef COPY_WSTR_ATTR
+#undef COPY_WSTRLIST
+ return _PyStatus_OK();
+}
+
+
+static PyObject *
+config_as_dict(const PyConfig *config)
+{
+ PyObject *dict;
+
+ dict = PyDict_New();
+ if (dict == NULL) {
+ return NULL;
+ }
+
+#define SET_ITEM(KEY, EXPR) \
+ do { \
+ PyObject *obj = (EXPR); \
+ if (obj == NULL) { \
+ goto fail; \
+ } \
+ int res = PyDict_SetItemString(dict, (KEY), obj); \
+ Py_DECREF(obj); \
+ if (res < 0) { \
+ goto fail; \
+ } \
+ } while (0)
+#define SET_ITEM_INT(ATTR) \
+ SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
+#define SET_ITEM_UINT(ATTR) \
+ SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
+#define FROM_WSTRING(STR) \
+ ((STR != NULL) ? \
+ PyUnicode_FromWideChar(STR, -1) \
+ : (Py_INCREF(Py_None), Py_None))
+#define SET_ITEM_WSTR(ATTR) \
+ SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
+#define SET_ITEM_WSTRLIST(LIST) \
+ SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
+
+ SET_ITEM_INT(_config_init);
+ SET_ITEM_INT(isolated);
+ SET_ITEM_INT(use_environment);
+ SET_ITEM_INT(dev_mode);
+ SET_ITEM_INT(_use_peg_parser);
+ SET_ITEM_INT(install_signal_handlers);
+ SET_ITEM_INT(use_hash_seed);
+ SET_ITEM_UINT(hash_seed);
+ SET_ITEM_INT(faulthandler);
+ SET_ITEM_INT(tracemalloc);
+ SET_ITEM_INT(import_time);
+ SET_ITEM_INT(show_ref_count);
+ SET_ITEM_INT(dump_refs);
+ SET_ITEM_INT(malloc_stats);
+ SET_ITEM_WSTR(filesystem_encoding);
+ SET_ITEM_WSTR(filesystem_errors);
+ SET_ITEM_WSTR(pycache_prefix);
+ SET_ITEM_WSTR(program_name);
+ SET_ITEM_INT(parse_argv);
+ SET_ITEM_WSTRLIST(argv);
+ SET_ITEM_WSTRLIST(xoptions);
+ SET_ITEM_WSTRLIST(warnoptions);
+ SET_ITEM_WSTR(pythonpath_env);
+ SET_ITEM_WSTR(home);
+ SET_ITEM_WSTRLIST(module_search_paths);
+ SET_ITEM_WSTR(executable);
+ SET_ITEM_WSTR(base_executable);
+ SET_ITEM_WSTR(prefix);
+ SET_ITEM_WSTR(base_prefix);
+ SET_ITEM_WSTR(exec_prefix);
+ SET_ITEM_WSTR(base_exec_prefix);
+ SET_ITEM_WSTR(platlibdir);
+ SET_ITEM_INT(site_import);
+ SET_ITEM_INT(bytes_warning);
+ SET_ITEM_INT(inspect);
+ SET_ITEM_INT(interactive);
+ SET_ITEM_INT(optimization_level);
+ SET_ITEM_INT(parser_debug);
+ SET_ITEM_INT(write_bytecode);
+ SET_ITEM_INT(verbose);
+ SET_ITEM_INT(quiet);
+ SET_ITEM_INT(user_site_directory);
+ SET_ITEM_INT(configure_c_stdio);
+ SET_ITEM_INT(buffered_stdio);
+ SET_ITEM_WSTR(stdio_encoding);
+ SET_ITEM_WSTR(stdio_errors);
+#ifdef MS_WINDOWS
+ SET_ITEM_INT(legacy_windows_stdio);
+#endif
+ SET_ITEM_INT(skip_source_first_line);
+ SET_ITEM_WSTR(run_command);
+ SET_ITEM_WSTR(run_module);
+ SET_ITEM_WSTR(run_filename);
+ SET_ITEM_INT(_install_importlib);
+ SET_ITEM_WSTR(check_hash_pycs_mode);
+ SET_ITEM_INT(pathconfig_warnings);
+ SET_ITEM_INT(_init_main);
+ SET_ITEM_INT(_isolated_interpreter);
+ SET_ITEM_WSTRLIST(_orig_argv);
+
+ return dict;
+
+fail:
+ Py_DECREF(dict);
+ return NULL;
+
+#undef FROM_WSTRING
+#undef SET_ITEM
+#undef SET_ITEM_INT
+#undef SET_ITEM_UINT
+#undef SET_ITEM_WSTR
+#undef SET_ITEM_WSTRLIST
+}
+
+
+static const char*
+config_get_env(const PyConfig *config, const char *name)
+{
+ return _Py_GetEnv(config->use_environment, name);
+}
+
+
+/* Get a copy of the environment variable as wchar_t*.
+ Return 0 on success, but *dest can be NULL.
+ Return -1 on memory allocation failure. Return -2 on decoding error. */
+static PyStatus
+config_get_env_dup(PyConfig *config,
+ wchar_t **dest,
+ wchar_t *wname, char *name,
+ const char *decode_err_msg)
+{
+ assert(*dest == NULL);
+ assert(config->use_environment >= 0);
+
+ if (!config->use_environment) {
+ *dest = NULL;
+ return _PyStatus_OK();
+ }
+
+#ifdef MS_WINDOWS
+ const wchar_t *var = _wgetenv(wname);
+ if (!var || var[0] == '\0') {
+ *dest = NULL;
+ return _PyStatus_OK();
+ }
+
+ return PyConfig_SetString(config, dest, var);
+#else
+ const char *var = getenv(name);
+ if (!var || var[0] == '\0') {
+ *dest = NULL;
+ return _PyStatus_OK();
+ }
+
+ return config_set_bytes_string(config, dest, var, decode_err_msg);
+#endif
+}
+
+
+#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
+ config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
+
+
+static void
+config_get_global_vars(PyConfig *config)
+{
+ if (config->_config_init != _PyConfig_INIT_COMPAT) {
+ /* Python and Isolated configuration ignore global variables */
+ return;
+ }
+
+#define COPY_FLAG(ATTR, VALUE) \
+ if (config->ATTR == -1) { \
+ config->ATTR = VALUE; \
+ }
+#define COPY_NOT_FLAG(ATTR, VALUE) \
+ if (config->ATTR == -1) { \
+ config->ATTR = !(VALUE); \
+ }
+
+ COPY_FLAG(isolated, Py_IsolatedFlag);
+ COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
+ COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
+ COPY_FLAG(inspect, Py_InspectFlag);
+ COPY_FLAG(interactive, Py_InteractiveFlag);
+ COPY_FLAG(optimization_level, Py_OptimizeFlag);
+ COPY_FLAG(parser_debug, Py_DebugFlag);
+ COPY_FLAG(verbose, Py_VerboseFlag);
+ COPY_FLAG(quiet, Py_QuietFlag);
+#ifdef MS_WINDOWS
+ COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
+#endif
+ COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
+
+ COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
+ COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
+ COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
+ COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
+
+#undef COPY_FLAG
+#undef COPY_NOT_FLAG
+}
+
+
+/* Set Py_xxx global configuration variables from 'config' configuration. */
+static void
+config_set_global_vars(const PyConfig *config)
+{
+#define COPY_FLAG(ATTR, VAR) \
+ if (config->ATTR != -1) { \
+ VAR = config->ATTR; \
+ }
+#define COPY_NOT_FLAG(ATTR, VAR) \
+ if (config->ATTR != -1) { \
+ VAR = !config->ATTR; \
+ }
+
+ COPY_FLAG(isolated, Py_IsolatedFlag);
+ COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
+ COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
+ COPY_FLAG(inspect, Py_InspectFlag);
+ COPY_FLAG(interactive, Py_InteractiveFlag);
+ COPY_FLAG(optimization_level, Py_OptimizeFlag);
+ COPY_FLAG(parser_debug, Py_DebugFlag);
+ COPY_FLAG(verbose, Py_VerboseFlag);
+ COPY_FLAG(quiet, Py_QuietFlag);
+#ifdef MS_WINDOWS
+ COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
+#endif
+ COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
+
+ COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
+ COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
+ COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
+ COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
+
+ /* Random or non-zero hash seed */
+ Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
+ config->hash_seed != 0);
+
+#undef COPY_FLAG
+#undef COPY_NOT_FLAG
+}
+
+
+/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
+ environment variables on macOS if available. */
+static PyStatus
+config_init_program_name(PyConfig *config)
+{
+ PyStatus status;
+
+ /* If Py_SetProgramName() was called, use its value */
+ const wchar_t *program_name = _Py_path_config.program_name;
+ if (program_name != NULL) {
+ config->program_name = _PyMem_RawWcsdup(program_name);
+ if (config->program_name == NULL) {
+ return _PyStatus_NO_MEMORY();
+ }
+ return _PyStatus_OK();
+ }
+
+#ifdef __APPLE__
+ /* On MacOS X, when the Python interpreter is embedded in an
+ application bundle, it gets executed by a bootstrapping script
+ that does os.execve() with an argv[0] that's different from the
+ actual Python executable. This is needed to keep the Finder happy,
+ or rather, to work around Apple's overly strict requirements of
+ the process name. However, we still need a usable sys.executable,
+ so the actual executable path is passed in an environment variable.
+ See Lib/plat-mac/bundlebuilder.py for details about the bootstrap
+ script. */
+ const char *p = config_get_env(config, "PYTHONEXECUTABLE");
+ if (p != NULL) {
+ status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
+ "PYTHONEXECUTABLE environment variable");
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ return _PyStatus_OK();
+ }
+#ifdef WITH_NEXT_FRAMEWORK
+ else {
+ const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
+ if (pyvenv_launcher && *pyvenv_launcher) {
+ /* Used by Mac/Tools/pythonw.c to forward
+ * the argv0 of the stub executable
+ */
+ status = CONFIG_SET_BYTES_STR(config,
+ &config->program_name,
+ pyvenv_launcher,
+ "__PYVENV_LAUNCHER__ environment variable");
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ /*
+ * This environment variable is used to communicate between
+ * the stub launcher and the real interpreter and isn't needed
+ * beyond this point.
+ *
+ * Clean up to avoid problems when launching other programs
+ * later on.
+ */
+ (void)unsetenv("__PYVENV_LAUNCHER__");
+
+ return _PyStatus_OK();
+ }
+ }
+#endif /* WITH_NEXT_FRAMEWORK */
+#endif /* __APPLE__ */
+
+ /* Use argv[0] if available and non-empty */
+ const PyWideStringList *argv = &config->argv;
+ if (argv->length >= 1 && argv->items[0][0] != L'\0') {
+ config->program_name = _PyMem_RawWcsdup(argv->items[0]);
+ if (config->program_name == NULL) {
+ return _PyStatus_NO_MEMORY();
+ }
+ return _PyStatus_OK();
+ }
+
+ /* Last fall back: hardcoded name */
+#ifdef MS_WINDOWS
+ const wchar_t *default_program_name = L"python";
+#else
+ const wchar_t *default_program_name = L"python3";
+#endif
+ status = PyConfig_SetString(config, &config->program_name,
+ default_program_name);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ return _PyStatus_OK();
+}
+
+static PyStatus
+config_init_executable(PyConfig *config)
+{
+ assert(config->executable == NULL);
+
+ /* If Py_SetProgramFullPath() was called, use its value */
+ const wchar_t *program_full_path = _Py_path_config.program_full_path;
+ if (program_full_path != NULL) {
+ PyStatus status = PyConfig_SetString(config,
+ &config->executable,
+ program_full_path);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ return _PyStatus_OK();
+ }
+ return _PyStatus_OK();
+}
+
+
+static const wchar_t*
+config_get_xoption(const PyConfig *config, wchar_t *name)
+{
+ return _Py_get_xoption(&config->xoptions, name);
+}
+
+
+static PyStatus
+config_init_home(PyConfig *config)
+{
+ assert(config->home == NULL);
+
+ /* If Py_SetPythonHome() was called, use its value */
+ wchar_t *home = _Py_path_config.home;
+ if (home) {
+ PyStatus status = PyConfig_SetString(config, &config->home, home);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ return _PyStatus_OK();
+ }
+
+ return CONFIG_GET_ENV_DUP(config, &config->home,
+ L"PYTHONHOME", "PYTHONHOME");
+}
+
+
+static PyStatus
+config_init_hash_seed(PyConfig *config)
+{
+ const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
+
+ Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
+ /* Convert a text seed to a numeric one */
+ if (seed_text && strcmp(seed_text, "random") != 0) {
+ const char *endptr = seed_text;
+ unsigned long seed;
+ errno = 0;
+ seed = strtoul(seed_text, (char **)&endptr, 10);
+ if (*endptr != '\0'
+ || seed > 4294967295UL
+ || (errno == ERANGE && seed == ULONG_MAX))
+ {
+ return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
+ "or an integer in range [0; 4294967295]");
+ }
+ /* Use a specific hash */
+ config->use_hash_seed = 1;
+ config->hash_seed = seed;
+ }
+ else {
+ /* Use a random hash */
+ config->use_hash_seed = 0;
+ config->hash_seed = 0;
+ }
+ return _PyStatus_OK();
+}
+
+
+static int
+config_wstr_to_int(const wchar_t *wstr, int *result)
+{
+ const wchar_t *endptr = wstr;
+ errno = 0;
+ long value = wcstol(wstr, (wchar_t **)&endptr, 10);
+ if (*endptr != '\0' || errno == ERANGE) {
+ return -1;
+ }
+ if (value < INT_MIN || value > INT_MAX) {
+ return -1;
+ }
+
+ *result = (int)value;
+ return 0;
+}
+
+
+static PyStatus
+config_read_env_vars(PyConfig *config)
+{
+ PyStatus status;
+ int use_env = config->use_environment;
+
+ /* Get environment variables */
+ _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
+ _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
+ _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
+ _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
+
+ int dont_write_bytecode = 0;
+ _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
+ if (dont_write_bytecode) {
+ config->write_bytecode = 0;
+ }
+
+ int no_user_site_directory = 0;
+ _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
+ if (no_user_site_directory) {
+ config->user_site_directory = 0;
+ }
+
+ int unbuffered_stdio = 0;
+ _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
+ if (unbuffered_stdio) {
+ config->buffered_stdio = 0;
+ }
+
+#ifdef MS_WINDOWS
+ _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
+ "PYTHONLEGACYWINDOWSSTDIO");
+#endif
+
+ if (config_get_env(config, "PYTHONDUMPREFS")) {
+ config->dump_refs = 1;
+ }
+ if (config_get_env(config, "PYTHONMALLOCSTATS")) {
+ config->malloc_stats = 1;
+ }
+
+ if (config->pythonpath_env == NULL) {
+ status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
+ L"PYTHONPATH", "PYTHONPATH");
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ if(config->platlibdir == NULL) {
+ status = CONFIG_GET_ENV_DUP(config, &config->platlibdir,
+ L"PYTHONPLATLIBDIR", "PYTHONPLATLIBDIR");
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ if (config->use_hash_seed < 0) {
+ status = config_init_hash_seed(config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ return _PyStatus_OK();
+}
+
+
+static PyStatus
+config_init_tracemalloc(PyConfig *config)
+{
+ int nframe;
+ int valid;
+
+ const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
+ if (env) {
+ if (!_Py_str_to_int(env, &nframe)) {
+ valid = (nframe >= 0);
+ }
+ else {
+ valid = 0;
+ }
+ if (!valid) {
+ return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
+ }
+ config->tracemalloc = nframe;
+ }
+
+ const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
+ if (xoption) {
+ const wchar_t *sep = wcschr(xoption, L'=');
+ if (sep) {
+ if (!config_wstr_to_int(sep + 1, &nframe)) {
+ valid = (nframe >= 0);
+ }
+ else {
+ valid = 0;
+ }
+ if (!valid) {
+ return _PyStatus_ERR("-X tracemalloc=NFRAME: "
+ "invalid number of frames");
+ }
+ }
+ else {
+ /* -X tracemalloc behaves as -X tracemalloc=1 */
+ nframe = 1;
+ }
+ config->tracemalloc = nframe;
+ }
+ return _PyStatus_OK();
+}
+
+
+static PyStatus
+config_init_pycache_prefix(PyConfig *config)
+{
+ assert(config->pycache_prefix == NULL);
+
+ const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
+ if (xoption) {
+ const wchar_t *sep = wcschr(xoption, L'=');
+ if (sep && wcslen(sep) > 1) {
+ config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
+ if (config->pycache_prefix == NULL) {
+ return _PyStatus_NO_MEMORY();
+ }
+ }
+ else {
+ // PYTHONPYCACHEPREFIX env var ignored
+ // if "-X pycache_prefix=" option is used
+ config->pycache_prefix = NULL;
+ }
+ return _PyStatus_OK();
+ }
+
+ return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
+ L"PYTHONPYCACHEPREFIX",
+ "PYTHONPYCACHEPREFIX");
+}
+
+
+static PyStatus
+config_read_complex_options(PyConfig *config)
+{
+ /* More complex options configured by env var and -X option */
+ if (config->faulthandler < 0) {
+ if (config_get_env(config, "PYTHONFAULTHANDLER")
+ || config_get_xoption(config, L"faulthandler")) {
+ config->faulthandler = 1;
+ }
+ }
+ if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
+ || config_get_xoption(config, L"importtime")) {
+ config->import_time = 1;
+ }
+
+ if (config_get_env(config, "PYTHONOLDPARSER")
+ || config_get_xoption(config, L"oldparser")) {
+ config->_use_peg_parser = 0;
+ }
+
+ PyStatus status;
+ if (config->tracemalloc < 0) {
+ status = config_init_tracemalloc(config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ if (config->pycache_prefix == NULL) {
+ status = config_init_pycache_prefix(config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+ return _PyStatus_OK();
+}
+
+
+static const wchar_t *
+config_get_stdio_errors(void)
+{
+#ifndef MS_WINDOWS
+ const char *loc = setlocale(LC_CTYPE, NULL);
+ if (loc != NULL) {
+ /* surrogateescape is the default in the legacy C and POSIX locales */
+ if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
+ return L"surrogateescape";
+ }
+
+#ifdef PY_COERCE_C_LOCALE
+ /* surrogateescape is the default in locale coercion target locales */
+ if (_Py_IsLocaleCoercionTarget(loc)) {
+ return L"surrogateescape";
+ }
+#endif
+ }
+
+ return L"strict";
+#else
+ /* On Windows, always use surrogateescape by default */
+ return L"surrogateescape";
+#endif
+}
+
+
+static PyStatus
+config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
+{
+#ifdef MS_WINDOWS
+ char encoding[20];
+ PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
+ return PyConfig_SetBytesString(config, locale_encoding, encoding);
+#elif defined(_Py_FORCE_UTF8_LOCALE)
+ return PyConfig_SetString(config, locale_encoding, L"utf-8");
+#else
+ const char *encoding = nl_langinfo(CODESET);
+ if (!encoding || encoding[0] == '\0') {
+ return _PyStatus_ERR("failed to get the locale encoding: "
+ "nl_langinfo(CODESET) failed");
+ }
+ /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
+ return CONFIG_SET_BYTES_STR(config,
+ locale_encoding, encoding,
+ "nl_langinfo(CODESET)");
+#endif
+}
+
+
+static PyStatus
+config_init_stdio_encoding(PyConfig *config,
+ const PyPreConfig *preconfig)
+{
+ PyStatus status;
+
+ /* If Py_SetStandardStreamEncoding() have been called, use these
+ parameters. */
+ if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
+ status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
+ _Py_StandardStreamEncoding,
+ "_Py_StandardStreamEncoding");
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
+ status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
+ _Py_StandardStreamErrors,
+ "_Py_StandardStreamErrors");
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
+ return _PyStatus_OK();
+ }
+
+ /* PYTHONIOENCODING environment variable */
+ const char *opt = config_get_env(config, "PYTHONIOENCODING");
+ if (opt) {
+ char *pythonioencoding = _PyMem_RawStrdup(opt);
+ if (pythonioencoding == NULL) {
+ return _PyStatus_NO_MEMORY();
+ }
+
+ char *errors = strchr(pythonioencoding, ':');
+ if (errors) {
+ *errors = '\0';
+ errors++;
+ if (!errors[0]) {
+ errors = NULL;
+ }
+ }
+
+ /* Does PYTHONIOENCODING contain an encoding? */
+ if (pythonioencoding[0]) {
+ if (config->stdio_encoding == NULL) {
+ status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
+ pythonioencoding,
+ "PYTHONIOENCODING environment variable");
+ if (_PyStatus_EXCEPTION(status)) {
+ PyMem_RawFree(pythonioencoding);
+ return status;
+ }
+ }
+
+ /* If the encoding is set but not the error handler,
+ use "strict" error handler by default.
+ PYTHONIOENCODING=latin1 behaves as
+ PYTHONIOENCODING=latin1:strict. */
+ if (!errors) {
+ errors = "strict";
+ }
+ }
+
+ if (config->stdio_errors == NULL && errors != NULL) {
+ status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
+ errors,
+ "PYTHONIOENCODING environment variable");
+ if (_PyStatus_EXCEPTION(status)) {
+ PyMem_RawFree(pythonioencoding);
+ return status;
+ }
+ }
+
+ PyMem_RawFree(pythonioencoding);
+ }
+
+ /* UTF-8 Mode uses UTF-8/surrogateescape */
+ if (preconfig->utf8_mode) {
+ if (config->stdio_encoding == NULL) {
+ status = PyConfig_SetString(config, &config->stdio_encoding,
+ L"utf-8");
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+ if (config->stdio_errors == NULL) {
+ status = PyConfig_SetString(config, &config->stdio_errors,
+ L"surrogateescape");
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+ }
+
+ /* Choose the default error handler based on the current locale. */
+ if (config->stdio_encoding == NULL) {
+ status = config_get_locale_encoding(config, &config->stdio_encoding);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+ if (config->stdio_errors == NULL) {
+ const wchar_t *errors = config_get_stdio_errors();
+ assert(errors != NULL);
+
+ status = PyConfig_SetString(config, &config->stdio_errors, errors);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ return _PyStatus_OK();
+}
+
+
+static PyStatus
+config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
+{
+ PyStatus status;
+
+ if (config->filesystem_encoding == NULL) {
+#ifdef _Py_FORCE_UTF8_FS_ENCODING
+ status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
+#else
+
+#ifdef MS_WINDOWS
+ if (preconfig->legacy_windows_fs_encoding) {
+ /* Legacy Windows filesystem encoding: mbcs/replace */
+ status = PyConfig_SetString(config, &config->filesystem_encoding,
+ L"mbcs");
+ }
+ else
+#endif
+ if (preconfig->utf8_mode) {
+ status = PyConfig_SetString(config, &config->filesystem_encoding,
+ L"utf-8");
+ }
+#ifndef MS_WINDOWS
+ else if (_Py_GetForceASCII()) {
+ status = PyConfig_SetString(config, &config->filesystem_encoding,
+ L"ascii");
+ }
+#endif
+ else {
+#ifdef MS_WINDOWS
+ /* Windows defaults to utf-8/surrogatepass (PEP 529). */
+ status = PyConfig_SetString(config, &config->filesystem_encoding,
+ L"utf-8");
+#else
+ status = config_get_locale_encoding(config,
+ &config->filesystem_encoding);
+#endif
+ }
+#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
+
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ if (config->filesystem_errors == NULL) {
+ const wchar_t *errors;
+#ifdef MS_WINDOWS
+ if (preconfig->legacy_windows_fs_encoding) {
+ errors = L"replace";
+ }
+ else {
+ errors = L"surrogatepass";
+ }
+#else
+ errors = L"surrogateescape";
+#endif
+ status = PyConfig_SetString(config, &config->filesystem_errors, errors);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+ return _PyStatus_OK();
+}
+
+
+static PyStatus
+config_read(PyConfig *config)
+{
+ PyStatus status;
+ const PyPreConfig *preconfig = &_PyRuntime.preconfig;
+
+ if (config->use_environment) {
+ status = config_read_env_vars(config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ /* -X options */
+ if (config_get_xoption(config, L"showrefcount")) {
+ config->show_ref_count = 1;
+ }
+
+ status = config_read_complex_options(config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ if (config->home == NULL) {
+ status = config_init_home(config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ if (config->executable == NULL) {
+ status = config_init_executable(config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ if(config->platlibdir == NULL) {
+ status = CONFIG_SET_BYTES_STR(config, &config->platlibdir, PLATLIBDIR,
+ "PLATLIBDIR macro");
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ if (config->_install_importlib) {
+ status = _PyConfig_InitPathConfig(config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ /* default values */
+ if (config->dev_mode) {
+ if (config->faulthandler < 0) {
+ config->faulthandler = 1;
+ }
+ }
+ if (config->faulthandler < 0) {
+ config->faulthandler = 0;
+ }
+ if (config->tracemalloc < 0) {
+ config->tracemalloc = 0;
+ }
+ if (config->use_hash_seed < 0) {
+ config->use_hash_seed = 0;
+ config->hash_seed = 0;
+ }
+
+ if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
+ status = config_init_fs_encoding(config, preconfig);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ status = config_init_stdio_encoding(config, preconfig);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ if (config->argv.length < 1) {
+ /* Ensure at least one (empty) argument is seen */
+ status = PyWideStringList_Append(&config->argv, L"");
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ if (config->check_hash_pycs_mode == NULL) {
+ status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
+ L"default");
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ if (config->configure_c_stdio < 0) {
+ config->configure_c_stdio = 1;
+ }
+
+ return _PyStatus_OK();
+}
+
+
+static void
+config_init_stdio(const PyConfig *config)
+{
+#if defined(MS_WINDOWS) || defined(__CYGWIN__)
+ /* don't translate newlines (\r\n <=> \n) */
+ _setmode(fileno(stdin), O_BINARY);
+ _setmode(fileno(stdout), O_BINARY);
+ _setmode(fileno(stderr), O_BINARY);
+#endif
+
+ if (!config->buffered_stdio) {
+#ifdef HAVE_SETVBUF
+ setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
+ setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
+ setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
+#else /* !HAVE_SETVBUF */
+ setbuf(stdin, (char *)NULL);
+ setbuf(stdout, (char *)NULL);
+ setbuf(stderr, (char *)NULL);
+#endif /* !HAVE_SETVBUF */
+ }
+ else if (config->interactive) {
+#ifdef MS_WINDOWS
+ /* Doesn't have to have line-buffered -- use unbuffered */
+ /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
+ setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
+#else /* !MS_WINDOWS */
+#ifdef HAVE_SETVBUF
+ setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
+ setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
+#endif /* HAVE_SETVBUF */
+#endif /* !MS_WINDOWS */
+ /* Leave stderr alone - it should be unbuffered anyway. */
+ }
+}
+
+
+/* Write the configuration:
+
+ - set Py_xxx global configuration variables
+ - initialize C standard streams (stdin, stdout, stderr) */
+PyStatus
+_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
+{
+ config_set_global_vars(config);
+
+ if (config->configure_c_stdio) {
+ config_init_stdio(config);
+ }
+
+ /* Write the new pre-configuration into _PyRuntime */
+ PyPreConfig *preconfig = &runtime->preconfig;
+ preconfig->isolated = config->isolated;
+ preconfig->use_environment = config->use_environment;
+ preconfig->dev_mode = config->dev_mode;
+
+ if (_Py_SetArgcArgv(config->_orig_argv.length,
+ config->_orig_argv.items) < 0)
+ {
+ return _PyStatus_NO_MEMORY();
+ }
+ return _PyStatus_OK();
+}
+
+
+/* --- PyConfig command line parser -------------------------- */
+
+static void
+config_usage(int error, const wchar_t* program)
+{
+ FILE *f = error ? stderr : stdout;
+
+ fprintf(f, usage_line, program);
+ if (error)
+ fprintf(f, "Try `python -h' for more information.\n");
+ else {
+ fputs(usage_1, f);
+ fputs(usage_2, f);
+ fputs(usage_3, f);
+ fprintf(f, usage_4, (wint_t)DELIM);
+ fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
+ fputs(usage_6, f);
+ }
+}
+
+
+/* Parse the command line arguments */
+static PyStatus
+config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
+ Py_ssize_t *opt_index)
+{
+ PyStatus status;
+ const PyWideStringList *argv = &config->argv;
+ int print_version = 0;
+ const wchar_t* program = config->program_name;
+
+ _PyOS_ResetGetOpt();
+ do {
+ int longindex = -1;
+ int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
+ if (c == EOF) {
+ break;
+ }
+
+ if (c == 'c') {
+ if (config->run_command == NULL) {
+ /* -c is the last option; following arguments
+ that look like options are left for the
+ command to interpret. */
+ size_t len = wcslen(_PyOS_optarg) + 1 + 1;
+ wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
+ if (command == NULL) {
+ return _PyStatus_NO_MEMORY();
+ }
+ memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
+ command[len - 2] = '\n';
+ command[len - 1] = 0;
+ config->run_command = command;
+ }
+ break;
+ }
+
+ if (c == 'm') {
+ /* -m is the last option; following arguments
+ that look like options are left for the
+ module to interpret. */
+ if (config->run_module == NULL) {
+ config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
+ if (config->run_module == NULL) {
+ return _PyStatus_NO_MEMORY();
+ }
+ }
+ break;
+ }
+
+ switch (c) {
+ case 0:
+ // Handle long option.
+ assert(longindex == 0); // Only one long option now.
+ if (wcscmp(_PyOS_optarg, L"always") == 0
+ || wcscmp(_PyOS_optarg, L"never") == 0
+ || wcscmp(_PyOS_optarg, L"default") == 0)
+ {
+ status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
+ _PyOS_optarg);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ } else {
+ fprintf(stderr, "--check-hash-based-pycs must be one of "
+ "'default', 'always', or 'never'\n");
+ config_usage(1, program);
+ return _PyStatus_EXIT(2);
+ }
+ break;
+
+ case 'b':
+ config->bytes_warning++;
+ break;
+
+ case 'd':
+ config->parser_debug++;
+ break;
+
+ case 'i':
+ config->inspect++;
+ config->interactive++;
+ break;
+
+ case 'E':
+ case 'I':
+ case 'X':
+ /* option handled by _PyPreCmdline_Read() */
+ break;
+
+ /* case 'J': reserved for Jython */
+
+ case 'O':
+ config->optimization_level++;
+ break;
+
+ case 'B':
+ config->write_bytecode = 0;
+ break;
+
+ case 's':
+ config->user_site_directory = 0;
+ break;
+
+ case 'S':
+ config->site_import = 0;
+ break;
+
+ case 't':
+ /* ignored for backwards compatibility */
+ break;
+
+ case 'u':
+ config->buffered_stdio = 0;
+ break;
+
+ case 'v':
+ config->verbose++;
+ break;
+
+ case 'x':
+ config->skip_source_first_line = 1;
+ break;
+
+ case 'h':
+ case '?':
+ config_usage(0, program);
+ return _PyStatus_EXIT(0);
+
+ case 'V':
+ print_version++;
+ break;
+
+ case 'W':
+ status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ break;
+
+ case 'q':
+ config->quiet++;
+ break;
+
+ case 'R':
+ config->use_hash_seed = 0;
+ break;
+
+ /* This space reserved for other options */
+
+ default:
+ /* unknown argument: parsing failed */
+ config_usage(1, program);
+ return _PyStatus_EXIT(2);
+ }
+ } while (1);
+
+ if (print_version) {
+ printf("Python %s\n",
+ (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
+ return _PyStatus_EXIT(0);
+ }
+
+ if (config->run_command == NULL && config->run_module == NULL
+ && _PyOS_optind < argv->length
+ && wcscmp(argv->items[_PyOS_optind], L"-") != 0
+ && config->run_filename == NULL)
+ {
+ config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
+ if (config->run_filename == NULL) {
+ return _PyStatus_NO_MEMORY();
+ }
+ }
+
+ if (config->run_command != NULL || config->run_module != NULL) {
+ /* Backup _PyOS_optind */
+ _PyOS_optind--;
+ }
+
+ *opt_index = _PyOS_optind;
+
+ return _PyStatus_OK();
+}
+
+
+#ifdef MS_WINDOWS
+# define WCSTOK wcstok_s
+#else
+# define WCSTOK wcstok
+#endif
+
+/* Get warning options from PYTHONWARNINGS environment variable. */
+static PyStatus
+config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
+{
+ PyStatus status;
+ /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
+ wchar_t *env = NULL;
+ status = CONFIG_GET_ENV_DUP(config, &env,
+ L"PYTHONWARNINGS", "PYTHONWARNINGS");
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ /* env var is not set or is empty */
+ if (env == NULL) {
+ return _PyStatus_OK();
+ }
+
+
+ wchar_t *warning, *context = NULL;
+ for (warning = WCSTOK(env, L",", &context);
+ warning != NULL;
+ warning = WCSTOK(NULL, L",", &context))
+ {
+ status = PyWideStringList_Append(warnoptions, warning);
+ if (_PyStatus_EXCEPTION(status)) {
+ PyMem_RawFree(env);
+ return status;
+ }
+ }
+ PyMem_RawFree(env);
+ return _PyStatus_OK();
+}
+
+
+static PyStatus
+warnoptions_append(PyConfig *config, PyWideStringList *options,
+ const wchar_t *option)
+{
+ /* config_init_warnoptions() add existing config warnoptions at the end:
+ ensure that the new option is not already present in this list to
+ prevent change the options order when config_init_warnoptions() is
+ called twice. */
+ if (_PyWideStringList_Find(&config->warnoptions, option)) {
+ /* Already present: do nothing */
+ return _PyStatus_OK();
+ }
+ if (_PyWideStringList_Find(options, option)) {
+ /* Already present: do nothing */
+ return _PyStatus_OK();
+ }
+ return PyWideStringList_Append(options, option);
+}
+
+
+static PyStatus
+warnoptions_extend(PyConfig *config, PyWideStringList *options,
+ const PyWideStringList *options2)
+{
+ const Py_ssize_t len = options2->length;
+ wchar_t *const *items = options2->items;
+
+ for (Py_ssize_t i = 0; i < len; i++) {
+ PyStatus status = warnoptions_append(config, options, items[i]);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+ return _PyStatus_OK();
+}
+
+
+static PyStatus
+config_init_warnoptions(PyConfig *config,
+ const PyWideStringList *cmdline_warnoptions,
+ const PyWideStringList *env_warnoptions,
+ const PyWideStringList *sys_warnoptions)
+{
+ PyStatus status;
+ PyWideStringList options = _PyWideStringList_INIT;
+
+ /* Priority of warnings options, lowest to highest:
+ *
+ * - any implicit filters added by _warnings.c/warnings.py
+ * - PyConfig.dev_mode: "default" filter
+ * - PYTHONWARNINGS environment variable
+ * - '-W' command line options
+ * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
+ * "default::BytesWarning" or "error::BytesWarning" filter
+ * - early PySys_AddWarnOption() calls
+ * - PyConfig.warnoptions
+ *
+ * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
+ * module works on the basis of "the most recently added filter will be
+ * checked first", we add the lowest precedence entries first so that later
+ * entries override them.
+ */
+
+ if (config->dev_mode) {
+ status = warnoptions_append(config, &options, L"default");
+ if (_PyStatus_EXCEPTION(status)) {
+ goto error;
+ }
+ }
+
+ status = warnoptions_extend(config, &options, env_warnoptions);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto error;
+ }
+
+ status = warnoptions_extend(config, &options, cmdline_warnoptions);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto error;
+ }
+
+ /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
+ * don't even try to emit a warning, so we skip setting the filter in that
+ * case.
+ */
+ if (config->bytes_warning) {
+ const wchar_t *filter;
+ if (config->bytes_warning> 1) {
+ filter = L"error::BytesWarning";
+ }
+ else {
+ filter = L"default::BytesWarning";
+ }
+ status = warnoptions_append(config, &options, filter);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto error;
+ }
+ }
+
+ status = warnoptions_extend(config, &options, sys_warnoptions);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto error;
+ }
+
+ /* Always add all PyConfig.warnoptions options */
+ status = _PyWideStringList_Extend(&options, &config->warnoptions);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto error;
+ }
+
+ _PyWideStringList_Clear(&config->warnoptions);
+ config->warnoptions = options;
+ return _PyStatus_OK();
+
+error:
+ _PyWideStringList_Clear(&options);
+ return status;
+}
+
+
+static PyStatus
+config_update_argv(PyConfig *config, Py_ssize_t opt_index)
+{
+ const PyWideStringList *cmdline_argv = &config->argv;
+ PyWideStringList config_argv = _PyWideStringList_INIT;
+
+ /* Copy argv to be able to modify it (to force -c/-m) */
+ if (cmdline_argv->length <= opt_index) {
+ /* Ensure at least one (empty) argument is seen */
+ PyStatus status = PyWideStringList_Append(&config_argv, L"");
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+ else {
+ PyWideStringList slice;
+ slice.length = cmdline_argv->length - opt_index;
+ slice.items = &cmdline_argv->items[opt_index];
+ if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
+ return _PyStatus_NO_MEMORY();
+ }
+ }
+ assert(config_argv.length >= 1);
+
+ wchar_t *arg0 = NULL;
+ if (config->run_command != NULL) {
+ /* Force sys.argv[0] = '-c' */
+ arg0 = L"-c";
+ }
+ else if (config->run_module != NULL) {
+ /* Force sys.argv[0] = '-m'*/
+ arg0 = L"-m";
+ }
+
+ if (arg0 != NULL) {
+ arg0 = _PyMem_RawWcsdup(arg0);
+ if (arg0 == NULL) {
+ _PyWideStringList_Clear(&config_argv);
+ return _PyStatus_NO_MEMORY();
+ }
+
+ PyMem_RawFree(config_argv.items[0]);
+ config_argv.items[0] = arg0;
+ }
+
+ _PyWideStringList_Clear(&config->argv);
+ config->argv = config_argv;
+ return _PyStatus_OK();
+}
+
+
+static PyStatus
+core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
+{
+ PyStatus status;
+
+ if (config->parse_argv) {
+ if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
+ return _PyStatus_NO_MEMORY();
+ }
+ }
+
+ PyPreConfig preconfig;
+
+ status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ _PyPreConfig_GetConfig(&preconfig, config);
+
+ status = _PyPreCmdline_Read(precmdline, &preconfig);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ status = _PyPreCmdline_SetConfig(precmdline, config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ return _PyStatus_OK();
+}
+
+
+/* Get run_filename absolute path */
+static PyStatus
+config_run_filename_abspath(PyConfig *config)
+{
+ if (!config->run_filename) {
+ return _PyStatus_OK();
+ }
+
+#ifndef MS_WINDOWS
+ if (_Py_isabs(config->run_filename)) {
+ /* path is already absolute */
+ return _PyStatus_OK();
+ }
+#endif
+
+ wchar_t *abs_filename;
+ if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
+ /* failed to get the absolute path of the command line filename:
+ ignore the error, keep the relative path */
+ return _PyStatus_OK();
+ }
+ if (abs_filename == NULL) {
+ return _PyStatus_NO_MEMORY();
+ }
+
+ PyMem_RawFree(config->run_filename);
+ config->run_filename = abs_filename;
+ return _PyStatus_OK();
+}
+
+
+static PyStatus
+config_read_cmdline(PyConfig *config)
+{
+ PyStatus status;
+ PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
+ PyWideStringList env_warnoptions = _PyWideStringList_INIT;
+ PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
+
+ if (config->parse_argv < 0) {
+ config->parse_argv = 1;
+ }
+
+ if (config->program_name == NULL) {
+ status = config_init_program_name(config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ if (config->parse_argv) {
+ Py_ssize_t opt_index;
+ status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+
+ status = config_run_filename_abspath(config);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+
+ status = config_update_argv(config, opt_index);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+ }
+ else {
+ status = config_run_filename_abspath(config);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+ }
+
+ if (config->use_environment) {
+ status = config_init_env_warnoptions(config, &env_warnoptions);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+ }
+
+ /* Handle early PySys_AddWarnOption() calls */
+ status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+
+ status = config_init_warnoptions(config,
+ &cmdline_warnoptions,
+ &env_warnoptions,
+ &sys_warnoptions);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+
+ status = _PyStatus_OK();
+
+done:
+ _PyWideStringList_Clear(&cmdline_warnoptions);
+ _PyWideStringList_Clear(&env_warnoptions);
+ _PyWideStringList_Clear(&sys_warnoptions);
+ return status;
+}
+
+
+PyStatus
+_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
+{
+ PyStatus status = _Py_PreInitializeFromConfig(config, args);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ return _PyArgv_AsWstrList(args, &config->argv);
+}
+
+
+/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
+ if needed to ensure that encodings are properly configured. */
+PyStatus
+PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
+{
+ _PyArgv args = {
+ .argc = argc,
+ .use_bytes_argv = 1,
+ .bytes_argv = argv,
+ .wchar_argv = NULL};
+ return _PyConfig_SetPyArgv(config, &args);
+}
+
+
+PyStatus
+PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
+{
+ _PyArgv args = {
+ .argc = argc,
+ .use_bytes_argv = 0,
+ .bytes_argv = NULL,
+ .wchar_argv = argv};
+ return _PyConfig_SetPyArgv(config, &args);
+}
+
+
+PyStatus
+PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
+ Py_ssize_t length, wchar_t **items)
+{
+ PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ PyWideStringList list2 = {.length = length, .items = items};
+ if (_PyWideStringList_Copy(list, &list2) < 0) {
+ return _PyStatus_NO_MEMORY();
+ }
+ return _PyStatus_OK();
+}
+
+
+/* Read the configuration into PyConfig from:
+
+ * Command line arguments
+ * Environment variables
+ * Py_xxx global configuration variables
+
+ The only side effects are to modify config and to call _Py_SetArgcArgv(). */
+PyStatus
+PyConfig_Read(PyConfig *config)
+{
+ PyStatus status;
+
+ status = _Py_PreInitializeFromConfig(config, NULL);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ config_get_global_vars(config);
+
+ if (config->_orig_argv.length == 0
+ && !(config->argv.length == 1
+ && wcscmp(config->argv.items[0], L"") == 0))
+ {
+ if (_PyWideStringList_Copy(&config->_orig_argv, &config->argv) < 0) {
+ return _PyStatus_NO_MEMORY();
+ }
+ }
+
+ _PyPreCmdline precmdline = _PyPreCmdline_INIT;
+ status = core_read_precmdline(config, &precmdline);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+
+ assert(config->isolated >= 0);
+ if (config->isolated) {
+ config->use_environment = 0;
+ config->user_site_directory = 0;
+ }
+
+ status = config_read_cmdline(config);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+
+ /* Handle early PySys_AddXOption() calls */
+ status = _PySys_ReadPreinitXOptions(config);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+
+ status = config_read(config);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+
+ /* Check config consistency */
+ assert(config->isolated >= 0);
+ assert(config->use_environment >= 0);
+ assert(config->dev_mode >= 0);
+ assert(config->_use_peg_parser >= 0);
+ assert(config->install_signal_handlers >= 0);
+ assert(config->use_hash_seed >= 0);
+ assert(config->faulthandler >= 0);
+ assert(config->tracemalloc >= 0);
+ assert(config->site_import >= 0);
+ assert(config->bytes_warning >= 0);
+ assert(config->inspect >= 0);
+ assert(config->interactive >= 0);
+ assert(config->optimization_level >= 0);
+ assert(config->parser_debug >= 0);
+ assert(config->write_bytecode >= 0);
+ assert(config->verbose >= 0);
+ assert(config->quiet >= 0);
+ assert(config->user_site_directory >= 0);
+ assert(config->parse_argv >= 0);
+ assert(config->configure_c_stdio >= 0);
+ assert(config->buffered_stdio >= 0);
+ assert(config->program_name != NULL);
+ assert(_PyWideStringList_CheckConsistency(&config->argv));
+ /* sys.argv must be non-empty: empty argv is replaced with [''] */
+ assert(config->argv.length >= 1);
+ assert(_PyWideStringList_CheckConsistency(&config->xoptions));
+ assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
+ assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
+ if (config->_install_importlib) {
+ assert(config->module_search_paths_set != 0);
+ /* don't check config->module_search_paths */
+ assert(config->executable != NULL);
+ assert(config->base_executable != NULL);
+ assert(config->prefix != NULL);
+ assert(config->base_prefix != NULL);
+ assert(config->exec_prefix != NULL);
+ assert(config->base_exec_prefix != NULL);
+ }
+ assert(config->platlibdir != NULL);
+ assert(config->filesystem_encoding != NULL);
+ assert(config->filesystem_errors != NULL);
+ assert(config->stdio_encoding != NULL);
+ assert(config->stdio_errors != NULL);
+#ifdef MS_WINDOWS
+ assert(config->legacy_windows_stdio >= 0);
+#endif
+ /* -c and -m options are exclusive */
+ assert(!(config->run_command != NULL && config->run_module != NULL));
+ assert(config->check_hash_pycs_mode != NULL);
+ assert(config->_install_importlib >= 0);
+ assert(config->pathconfig_warnings >= 0);
+ assert(_PyWideStringList_CheckConsistency(&config->_orig_argv));
+
+ status = _PyStatus_OK();
+
+done:
+ _PyPreCmdline_Clear(&precmdline);
+ return status;
+}
+
+
+PyObject*
+_Py_GetConfigsAsDict(void)
+{
+ PyObject *result = NULL;
+ PyObject *dict = NULL;
+
+ result = PyDict_New();
+ if (result == NULL) {
+ goto error;
+ }
+
+ /* global result */
+ dict = _Py_GetGlobalVariablesAsDict();
+ if (dict == NULL) {
+ goto error;
+ }
+ if (PyDict_SetItemString(result, "global_config", dict) < 0) {
+ goto error;
+ }
+ Py_CLEAR(dict);
+
+ /* pre config */
+ PyThreadState *tstate = _PyThreadState_GET();
+ const PyPreConfig *pre_config = &tstate->interp->runtime->preconfig;
+ dict = _PyPreConfig_AsDict(pre_config);
+ if (dict == NULL) {
+ goto error;
+ }
+ if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
+ goto error;
+ }
+ Py_CLEAR(dict);
+
+ /* core config */
+ const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
+ dict = config_as_dict(config);
+ if (dict == NULL) {
+ goto error;
+ }
+ if (PyDict_SetItemString(result, "config", dict) < 0) {
+ goto error;
+ }
+ Py_CLEAR(dict);
+
+ return result;
+
+error:
+ Py_XDECREF(result);
+ Py_XDECREF(dict);
+ return NULL;
+}
+
+
+static void
+init_dump_ascii_wstr(const wchar_t *str)
+{
+ if (str == NULL) {
+ PySys_WriteStderr("(not set)");
+ return;
+ }
+
+ PySys_WriteStderr("'");
+ for (; *str != L'\0'; str++) {
+ unsigned int ch = (unsigned int)*str;
+ if (ch == L'\'') {
+ PySys_WriteStderr("\\'");
+ } else if (0x20 <= ch && ch < 0x7f) {
+ PySys_WriteStderr("%c", ch);
+ }
+ else if (ch <= 0xff) {
+ PySys_WriteStderr("\\x%02x", ch);
+ }
+#if SIZEOF_WCHAR_T > 2
+ else if (ch > 0xffff) {
+ PySys_WriteStderr("\\U%08x", ch);
+ }
+#endif
+ else {
+ PySys_WriteStderr("\\u%04x", ch);
+ }
+ }
+ PySys_WriteStderr("'");
+}
+
+
+/* Dump the Python path configuration into sys.stderr */
+void
+_Py_DumpPathConfig(PyThreadState *tstate)
+{
+ PyObject *exc_type, *exc_value, *exc_tb;
+ _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
+
+ PySys_WriteStderr("Python path configuration:\n");
+
+#define DUMP_CONFIG(NAME, FIELD) \
+ do { \
+ PySys_WriteStderr(" " NAME " = "); \
+ init_dump_ascii_wstr(config->FIELD); \
+ PySys_WriteStderr("\n"); \
+ } while (0)
+
+ const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
+ DUMP_CONFIG("PYTHONHOME", home);
+ DUMP_CONFIG("PYTHONPATH", pythonpath_env);
+ DUMP_CONFIG("program name", program_name);
+ PySys_WriteStderr(" isolated = %i\n", config->isolated);
+ PySys_WriteStderr(" environment = %i\n", config->use_environment);
+ PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
+ PySys_WriteStderr(" import site = %i\n", config->site_import);
+#undef DUMP_CONFIG
+
+#define DUMP_SYS(NAME) \
+ do { \
+ obj = PySys_GetObject(#NAME); \
+ PySys_FormatStderr(" sys.%s = ", #NAME); \
+ if (obj != NULL) { \
+ PySys_FormatStderr("%A", obj); \
+ } \
+ else { \
+ PySys_WriteStderr("(not set)"); \
+ } \
+ PySys_FormatStderr("\n"); \
+ } while (0)
+
+ PyObject *obj;
+ DUMP_SYS(_base_executable);
+ DUMP_SYS(base_prefix);
+ DUMP_SYS(base_exec_prefix);
+ DUMP_SYS(platlibdir);
+ DUMP_SYS(executable);
+ DUMP_SYS(prefix);
+ DUMP_SYS(exec_prefix);
+#undef DUMP_SYS
+
+ PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
+ if (sys_path != NULL && PyList_Check(sys_path)) {
+ PySys_WriteStderr(" sys.path = [\n");
+ Py_ssize_t len = PyList_GET_SIZE(sys_path);
+ for (Py_ssize_t i=0; i < len; i++) {
+ PyObject *path = PyList_GET_ITEM(sys_path, i);
+ PySys_FormatStderr(" %A,\n", path);
+ }
+ PySys_WriteStderr(" ]\n");
+ }
+
+ _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
+}
diff --git a/contrib/tools/python3/src/Python/marshal.c b/contrib/tools/python3/src/Python/marshal.c
new file mode 100644
index 00000000000..baafa3ecfbf
--- /dev/null
+++ b/contrib/tools/python3/src/Python/marshal.c
@@ -0,0 +1,1822 @@
+
+/* Write Python objects to files and read them back.
+ This is primarily intended for writing and reading compiled Python code,
+ even though dicts, lists, sets and frozensets, not commonly seen in
+ code objects, are supported.
+ Version 3 of this protocol properly supports circular links
+ and sharing. */
+
+#define PY_SSIZE_T_CLEAN
+
+#include "Python.h"
+#include "longintrepr.h"
+#include "code.h"
+#include "marshal.h"
+#include "pycore_hashtable.h"
+
+/*[clinic input]
+module marshal
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c982b7930dee17db]*/
+
+#include "clinic/marshal.c.h"
+
+/* High water mark to determine when the marshalled object is dangerously deep
+ * and risks coring the interpreter. When the object stack gets this deep,
+ * raise an exception instead of continuing.
+ * On Windows debug builds, reduce this value.
+ *
+ * BUG: https://bugs.python.org/issue33720
+ * On Windows PGO builds, the r_object function overallocates its stack and
+ * can cause a stack overflow. We reduce the maximum depth for all Windows
+ * releases to protect against this.
+ * #if defined(MS_WINDOWS) && defined(_DEBUG)
+ */
+#if defined(MS_WINDOWS)
+#define MAX_MARSHAL_STACK_DEPTH 1000
+#else
+#define MAX_MARSHAL_STACK_DEPTH 2000
+#endif
+
+#define TYPE_NULL '0'
+#define TYPE_NONE 'N'
+#define TYPE_FALSE 'F'
+#define TYPE_TRUE 'T'
+#define TYPE_STOPITER 'S'
+#define TYPE_ELLIPSIS '.'
+#define TYPE_INT 'i'
+/* TYPE_INT64 is not generated anymore.
+ Supported for backward compatibility only. */
+#define TYPE_INT64 'I'
+#define TYPE_FLOAT 'f'
+#define TYPE_BINARY_FLOAT 'g'
+#define TYPE_COMPLEX 'x'
+#define TYPE_BINARY_COMPLEX 'y'
+#define TYPE_LONG 'l'
+#define TYPE_STRING 's'
+#define TYPE_INTERNED 't'
+#define TYPE_REF 'r'
+#define TYPE_TUPLE '('
+#define TYPE_LIST '['
+#define TYPE_DICT '{'
+#define TYPE_CODE 'c'
+#define TYPE_UNICODE 'u'
+#define TYPE_UNKNOWN '?'
+#define TYPE_SET '<'
+#define TYPE_FROZENSET '>'
+#define FLAG_REF '\x80' /* with a type, add obj to index */
+
+#define TYPE_ASCII 'a'
+#define TYPE_ASCII_INTERNED 'A'
+#define TYPE_SMALL_TUPLE ')'
+#define TYPE_SHORT_ASCII 'z'
+#define TYPE_SHORT_ASCII_INTERNED 'Z'
+
+#define WFERR_OK 0
+#define WFERR_UNMARSHALLABLE 1
+#define WFERR_NESTEDTOODEEP 2
+#define WFERR_NOMEMORY 3
+
+typedef struct {
+ FILE *fp;
+ int error; /* see WFERR_* values */
+ int depth;
+ PyObject *str;
+ char *ptr;
+ const char *end;
+ char *buf;
+ _Py_hashtable_t *hashtable;
+ int version;
+} WFILE;
+
+#define w_byte(c, p) do { \
+ if ((p)->ptr != (p)->end || w_reserve((p), 1)) \
+ *(p)->ptr++ = (c); \
+ } while(0)
+
+static void
+w_flush(WFILE *p)
+{
+ assert(p->fp != NULL);
+ fwrite(p->buf, 1, p->ptr - p->buf, p->fp);
+ p->ptr = p->buf;
+}
+
+static int
+w_reserve(WFILE *p, Py_ssize_t needed)
+{
+ Py_ssize_t pos, size, delta;
+ if (p->ptr == NULL)
+ return 0; /* An error already occurred */
+ if (p->fp != NULL) {
+ w_flush(p);
+ return needed <= p->end - p->ptr;
+ }
+ assert(p->str != NULL);
+ pos = p->ptr - p->buf;
+ size = PyBytes_GET_SIZE(p->str);
+ if (size > 16*1024*1024)
+ delta = (size >> 3); /* 12.5% overallocation */
+ else
+ delta = size + 1024;
+ delta = Py_MAX(delta, needed);
+ if (delta > PY_SSIZE_T_MAX - size) {
+ p->error = WFERR_NOMEMORY;
+ return 0;
+ }
+ size += delta;
+ if (_PyBytes_Resize(&p->str, size) != 0) {
+ p->end = p->ptr = p->buf = NULL;
+ return 0;
+ }
+ else {
+ p->buf = PyBytes_AS_STRING(p->str);
+ p->ptr = p->buf + pos;
+ p->end = p->buf + size;
+ return 1;
+ }
+}
+
+static void
+w_string(const void *s, Py_ssize_t n, WFILE *p)
+{
+ Py_ssize_t m;
+ if (!n || p->ptr == NULL)
+ return;
+ m = p->end - p->ptr;
+ if (p->fp != NULL) {
+ if (n <= m) {
+ memcpy(p->ptr, s, n);
+ p->ptr += n;
+ }
+ else {
+ w_flush(p);
+ fwrite(s, 1, n, p->fp);
+ }
+ }
+ else {
+ if (n <= m || w_reserve(p, n - m)) {
+ memcpy(p->ptr, s, n);
+ p->ptr += n;
+ }
+ }
+}
+
+static void
+w_short(int x, WFILE *p)
+{
+ w_byte((char)( x & 0xff), p);
+ w_byte((char)((x>> 8) & 0xff), p);
+}
+
+static void
+w_long(long x, WFILE *p)
+{
+ w_byte((char)( x & 0xff), p);
+ w_byte((char)((x>> 8) & 0xff), p);
+ w_byte((char)((x>>16) & 0xff), p);
+ w_byte((char)((x>>24) & 0xff), p);
+}
+
+#define SIZE32_MAX 0x7FFFFFFF
+
+#if SIZEOF_SIZE_T > 4
+# define W_SIZE(n, p) do { \
+ if ((n) > SIZE32_MAX) { \
+ (p)->depth--; \
+ (p)->error = WFERR_UNMARSHALLABLE; \
+ return; \
+ } \
+ w_long((long)(n), p); \
+ } while(0)
+#else
+# define W_SIZE w_long
+#endif
+
+static void
+w_pstring(const void *s, Py_ssize_t n, WFILE *p)
+{
+ W_SIZE(n, p);
+ w_string(s, n, p);
+}
+
+static void
+w_short_pstring(const void *s, Py_ssize_t n, WFILE *p)
+{
+ w_byte(Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char), p);
+ w_string(s, n, p);
+}
+
+/* We assume that Python ints are stored internally in base some power of
+ 2**15; for the sake of portability we'll always read and write them in base
+ exactly 2**15. */
+
+#define PyLong_MARSHAL_SHIFT 15
+#define PyLong_MARSHAL_BASE ((short)1 << PyLong_MARSHAL_SHIFT)
+#define PyLong_MARSHAL_MASK (PyLong_MARSHAL_BASE - 1)
+#if PyLong_SHIFT % PyLong_MARSHAL_SHIFT != 0
+#error "PyLong_SHIFT must be a multiple of PyLong_MARSHAL_SHIFT"
+#endif
+#define PyLong_MARSHAL_RATIO (PyLong_SHIFT / PyLong_MARSHAL_SHIFT)
+
+#define W_TYPE(t, p) do { \
+ w_byte((t) | flag, (p)); \
+} while(0)
+
+static void
+w_PyLong(const PyLongObject *ob, char flag, WFILE *p)
+{
+ Py_ssize_t i, j, n, l;
+ digit d;
+
+ W_TYPE(TYPE_LONG, p);
+ if (Py_SIZE(ob) == 0) {
+ w_long((long)0, p);
+ return;
+ }
+
+ /* set l to number of base PyLong_MARSHAL_BASE digits */
+ n = Py_ABS(Py_SIZE(ob));
+ l = (n-1) * PyLong_MARSHAL_RATIO;
+ d = ob->ob_digit[n-1];
+ assert(d != 0); /* a PyLong is always normalized */
+ do {
+ d >>= PyLong_MARSHAL_SHIFT;
+ l++;
+ } while (d != 0);
+ if (l > SIZE32_MAX) {
+ p->depth--;
+ p->error = WFERR_UNMARSHALLABLE;
+ return;
+ }
+ w_long((long)(Py_SIZE(ob) > 0 ? l : -l), p);
+
+ for (i=0; i < n-1; i++) {
+ d = ob->ob_digit[i];
+ for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
+ w_short(d & PyLong_MARSHAL_MASK, p);
+ d >>= PyLong_MARSHAL_SHIFT;
+ }
+ assert (d == 0);
+ }
+ d = ob->ob_digit[n-1];
+ do {
+ w_short(d & PyLong_MARSHAL_MASK, p);
+ d >>= PyLong_MARSHAL_SHIFT;
+ } while (d != 0);
+}
+
+static void
+w_float_bin(double v, WFILE *p)
+{
+ unsigned char buf[8];
+ if (_PyFloat_Pack8(v, buf, 1) < 0) {
+ p->error = WFERR_UNMARSHALLABLE;
+ return;
+ }
+ w_string(buf, 8, p);
+}
+
+static void
+w_float_str(double v, WFILE *p)
+{
+ char *buf = PyOS_double_to_string(v, 'g', 17, 0, NULL);
+ if (!buf) {
+ p->error = WFERR_NOMEMORY;
+ return;
+ }
+ w_short_pstring(buf, strlen(buf), p);
+ PyMem_Free(buf);
+}
+
+static int
+w_ref(PyObject *v, char *flag, WFILE *p)
+{
+ _Py_hashtable_entry_t *entry;
+ int w;
+
+ if (p->version < 3 || p->hashtable == NULL)
+ return 0; /* not writing object references */
+
+ /* if it has only one reference, it definitely isn't shared */
+ if (Py_REFCNT(v) == 1)
+ return 0;
+
+ entry = _Py_hashtable_get_entry(p->hashtable, v);
+ if (entry != NULL) {
+ /* write the reference index to the stream */
+ w = (int)(uintptr_t)entry->value;
+ /* we don't store "long" indices in the dict */
+ assert(0 <= w && w <= 0x7fffffff);
+ w_byte(TYPE_REF, p);
+ w_long(w, p);
+ return 1;
+ } else {
+ size_t s = p->hashtable->nentries;
+ /* we don't support long indices */
+ if (s >= 0x7fffffff) {
+ PyErr_SetString(PyExc_ValueError, "too many objects");
+ goto err;
+ }
+ w = (int)s;
+ Py_INCREF(v);
+ if (_Py_hashtable_set(p->hashtable, v, (void *)(uintptr_t)w) < 0) {
+ Py_DECREF(v);
+ goto err;
+ }
+ *flag |= FLAG_REF;
+ return 0;
+ }
+err:
+ p->error = WFERR_UNMARSHALLABLE;
+ return 1;
+}
+
+static void
+w_complex_object(PyObject *v, char flag, WFILE *p);
+
+static void
+w_object(PyObject *v, WFILE *p)
+{
+ char flag = '\0';
+
+ p->depth++;
+
+ if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
+ p->error = WFERR_NESTEDTOODEEP;
+ }
+ else if (v == NULL) {
+ w_byte(TYPE_NULL, p);
+ }
+ else if (v == Py_None) {
+ w_byte(TYPE_NONE, p);
+ }
+ else if (v == PyExc_StopIteration) {
+ w_byte(TYPE_STOPITER, p);
+ }
+ else if (v == Py_Ellipsis) {
+ w_byte(TYPE_ELLIPSIS, p);
+ }
+ else if (v == Py_False) {
+ w_byte(TYPE_FALSE, p);
+ }
+ else if (v == Py_True) {
+ w_byte(TYPE_TRUE, p);
+ }
+ else if (!w_ref(v, &flag, p))
+ w_complex_object(v, flag, p);
+
+ p->depth--;
+}
+
+static void
+w_complex_object(PyObject *v, char flag, WFILE *p)
+{
+ Py_ssize_t i, n;
+
+ if (PyLong_CheckExact(v)) {
+ int overflow;
+ long x = PyLong_AsLongAndOverflow(v, &overflow);
+ if (overflow) {
+ w_PyLong((PyLongObject *)v, flag, p);
+ }
+ else {
+#if SIZEOF_LONG > 4
+ long y = Py_ARITHMETIC_RIGHT_SHIFT(long, x, 31);
+ if (y && y != -1) {
+ /* Too large for TYPE_INT */
+ w_PyLong((PyLongObject*)v, flag, p);
+ }
+ else
+#endif
+ {
+ W_TYPE(TYPE_INT, p);
+ w_long(x, p);
+ }
+ }
+ }
+ else if (PyFloat_CheckExact(v)) {
+ if (p->version > 1) {
+ W_TYPE(TYPE_BINARY_FLOAT, p);
+ w_float_bin(PyFloat_AS_DOUBLE(v), p);
+ }
+ else {
+ W_TYPE(TYPE_FLOAT, p);
+ w_float_str(PyFloat_AS_DOUBLE(v), p);
+ }
+ }
+ else if (PyComplex_CheckExact(v)) {
+ if (p->version > 1) {
+ W_TYPE(TYPE_BINARY_COMPLEX, p);
+ w_float_bin(PyComplex_RealAsDouble(v), p);
+ w_float_bin(PyComplex_ImagAsDouble(v), p);
+ }
+ else {
+ W_TYPE(TYPE_COMPLEX, p);
+ w_float_str(PyComplex_RealAsDouble(v), p);
+ w_float_str(PyComplex_ImagAsDouble(v), p);
+ }
+ }
+ else if (PyBytes_CheckExact(v)) {
+ W_TYPE(TYPE_STRING, p);
+ w_pstring(PyBytes_AS_STRING(v), PyBytes_GET_SIZE(v), p);
+ }
+ else if (PyUnicode_CheckExact(v)) {
+ if (p->version >= 4 && PyUnicode_IS_ASCII(v)) {
+ int is_short = PyUnicode_GET_LENGTH(v) < 256;
+ if (is_short) {
+ if (PyUnicode_CHECK_INTERNED(v))
+ W_TYPE(TYPE_SHORT_ASCII_INTERNED, p);
+ else
+ W_TYPE(TYPE_SHORT_ASCII, p);
+ w_short_pstring(PyUnicode_1BYTE_DATA(v),
+ PyUnicode_GET_LENGTH(v), p);
+ }
+ else {
+ if (PyUnicode_CHECK_INTERNED(v))
+ W_TYPE(TYPE_ASCII_INTERNED, p);
+ else
+ W_TYPE(TYPE_ASCII, p);
+ w_pstring(PyUnicode_1BYTE_DATA(v),
+ PyUnicode_GET_LENGTH(v), p);
+ }
+ }
+ else {
+ PyObject *utf8;
+ utf8 = PyUnicode_AsEncodedString(v, "utf8", "surrogatepass");
+ if (utf8 == NULL) {
+ p->depth--;
+ p->error = WFERR_UNMARSHALLABLE;
+ return;
+ }
+ if (p->version >= 3 && PyUnicode_CHECK_INTERNED(v))
+ W_TYPE(TYPE_INTERNED, p);
+ else
+ W_TYPE(TYPE_UNICODE, p);
+ w_pstring(PyBytes_AS_STRING(utf8), PyBytes_GET_SIZE(utf8), p);
+ Py_DECREF(utf8);
+ }
+ }
+ else if (PyTuple_CheckExact(v)) {
+ n = PyTuple_GET_SIZE(v);
+ if (p->version >= 4 && n < 256) {
+ W_TYPE(TYPE_SMALL_TUPLE, p);
+ w_byte((unsigned char)n, p);
+ }
+ else {
+ W_TYPE(TYPE_TUPLE, p);
+ W_SIZE(n, p);
+ }
+ for (i = 0; i < n; i++) {
+ w_object(PyTuple_GET_ITEM(v, i), p);
+ }
+ }
+ else if (PyList_CheckExact(v)) {
+ W_TYPE(TYPE_LIST, p);
+ n = PyList_GET_SIZE(v);
+ W_SIZE(n, p);
+ for (i = 0; i < n; i++) {
+ w_object(PyList_GET_ITEM(v, i), p);
+ }
+ }
+ else if (PyDict_CheckExact(v)) {
+ Py_ssize_t pos;
+ PyObject *key, *value;
+ W_TYPE(TYPE_DICT, p);
+ /* This one is NULL object terminated! */
+ pos = 0;
+ while (PyDict_Next(v, &pos, &key, &value)) {
+ w_object(key, p);
+ w_object(value, p);
+ }
+ w_object((PyObject *)NULL, p);
+ }
+ else if (PyAnySet_CheckExact(v)) {
+ PyObject *value;
+ Py_ssize_t pos = 0;
+ Py_hash_t hash;
+
+ if (PyFrozenSet_CheckExact(v))
+ W_TYPE(TYPE_FROZENSET, p);
+ else
+ W_TYPE(TYPE_SET, p);
+ n = PySet_GET_SIZE(v);
+ W_SIZE(n, p);
+ while (_PySet_NextEntry(v, &pos, &value, &hash)) {
+ w_object(value, p);
+ }
+ }
+ else if (PyCode_Check(v)) {
+ PyCodeObject *co = (PyCodeObject *)v;
+ W_TYPE(TYPE_CODE, p);
+ w_long(co->co_argcount, p);
+ w_long(co->co_posonlyargcount, p);
+ w_long(co->co_kwonlyargcount, p);
+ w_long(co->co_nlocals, p);
+ w_long(co->co_stacksize, p);
+ w_long(co->co_flags, p);
+ w_object(co->co_code, p);
+ w_object(co->co_consts, p);
+ w_object(co->co_names, p);
+ w_object(co->co_varnames, p);
+ w_object(co->co_freevars, p);
+ w_object(co->co_cellvars, p);
+ w_object(co->co_filename, p);
+ w_object(co->co_name, p);
+ w_long(co->co_firstlineno, p);
+ w_object(co->co_lnotab, p);
+ }
+ else if (PyObject_CheckBuffer(v)) {
+ /* Write unknown bytes-like objects as a bytes object */
+ Py_buffer view;
+ if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) != 0) {
+ w_byte(TYPE_UNKNOWN, p);
+ p->depth--;
+ p->error = WFERR_UNMARSHALLABLE;
+ return;
+ }
+ W_TYPE(TYPE_STRING, p);
+ w_pstring(view.buf, view.len, p);
+ PyBuffer_Release(&view);
+ }
+ else {
+ W_TYPE(TYPE_UNKNOWN, p);
+ p->error = WFERR_UNMARSHALLABLE;
+ }
+}
+
+static void
+w_decref_entry(void *key)
+{
+ PyObject *entry_key = (PyObject *)key;
+ Py_XDECREF(entry_key);
+}
+
+static int
+w_init_refs(WFILE *wf, int version)
+{
+ if (version >= 3) {
+ wf->hashtable = _Py_hashtable_new_full(_Py_hashtable_hash_ptr,
+ _Py_hashtable_compare_direct,
+ w_decref_entry, NULL, NULL);
+ if (wf->hashtable == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static void
+w_clear_refs(WFILE *wf)
+{
+ if (wf->hashtable != NULL) {
+ _Py_hashtable_destroy(wf->hashtable);
+ }
+}
+
+/* version currently has no effect for writing ints. */
+void
+PyMarshal_WriteLongToFile(long x, FILE *fp, int version)
+{
+ char buf[4];
+ WFILE wf;
+ memset(&wf, 0, sizeof(wf));
+ wf.fp = fp;
+ wf.ptr = wf.buf = buf;
+ wf.end = wf.ptr + sizeof(buf);
+ wf.error = WFERR_OK;
+ wf.version = version;
+ w_long(x, &wf);
+ w_flush(&wf);
+}
+
+void
+PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
+{
+ char buf[BUFSIZ];
+ WFILE wf;
+ if (PySys_Audit("marshal.dumps", "Oi", x, version) < 0) {
+ return; /* caller must check PyErr_Occurred() */
+ }
+ memset(&wf, 0, sizeof(wf));
+ wf.fp = fp;
+ wf.ptr = wf.buf = buf;
+ wf.end = wf.ptr + sizeof(buf);
+ wf.error = WFERR_OK;
+ wf.version = version;
+ if (w_init_refs(&wf, version)) {
+ return; /* caller must check PyErr_Occurred() */
+ }
+ w_object(x, &wf);
+ w_clear_refs(&wf);
+ w_flush(&wf);
+}
+
+typedef struct {
+ FILE *fp;
+ int depth;
+ PyObject *readable; /* Stream-like object being read from */
+ const char *ptr;
+ const char *end;
+ char *buf;
+ Py_ssize_t buf_size;
+ PyObject *refs; /* a list */
+} RFILE;
+
+static const char *
+r_string(Py_ssize_t n, RFILE *p)
+{
+ Py_ssize_t read = -1;
+
+ if (p->ptr != NULL) {
+ /* Fast path for loads() */
+ const char *res = p->ptr;
+ Py_ssize_t left = p->end - p->ptr;
+ if (left < n) {
+ PyErr_SetString(PyExc_EOFError,
+ "marshal data too short");
+ return NULL;
+ }
+ p->ptr += n;
+ return res;
+ }
+ if (p->buf == NULL) {
+ p->buf = PyMem_MALLOC(n);
+ if (p->buf == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ p->buf_size = n;
+ }
+ else if (p->buf_size < n) {
+ char *tmp = PyMem_REALLOC(p->buf, n);
+ if (tmp == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ p->buf = tmp;
+ p->buf_size = n;
+ }
+
+ if (!p->readable) {
+ assert(p->fp != NULL);
+ read = fread(p->buf, 1, n, p->fp);
+ }
+ else {
+ _Py_IDENTIFIER(readinto);
+ PyObject *res, *mview;
+ Py_buffer buf;
+
+ if (PyBuffer_FillInfo(&buf, NULL, p->buf, n, 0, PyBUF_CONTIG) == -1)
+ return NULL;
+ mview = PyMemoryView_FromBuffer(&buf);
+ if (mview == NULL)
+ return NULL;
+
+ res = _PyObject_CallMethodId(p->readable, &PyId_readinto, "N", mview);
+ if (res != NULL) {
+ read = PyNumber_AsSsize_t(res, PyExc_ValueError);
+ Py_DECREF(res);
+ }
+ }
+ if (read != n) {
+ if (!PyErr_Occurred()) {
+ if (read > n)
+ PyErr_Format(PyExc_ValueError,
+ "read() returned too much data: "
+ "%zd bytes requested, %zd returned",
+ n, read);
+ else
+ PyErr_SetString(PyExc_EOFError,
+ "EOF read where not expected");
+ }
+ return NULL;
+ }
+ return p->buf;
+}
+
+static int
+r_byte(RFILE *p)
+{
+ int c = EOF;
+
+ if (p->ptr != NULL) {
+ if (p->ptr < p->end)
+ c = (unsigned char) *p->ptr++;
+ return c;
+ }
+ if (!p->readable) {
+ assert(p->fp);
+ c = getc(p->fp);
+ }
+ else {
+ const char *ptr = r_string(1, p);
+ if (ptr != NULL)
+ c = *(const unsigned char *) ptr;
+ }
+ return c;
+}
+
+static int
+r_short(RFILE *p)
+{
+ short x = -1;
+ const unsigned char *buffer;
+
+ buffer = (const unsigned char *) r_string(2, p);
+ if (buffer != NULL) {
+ x = buffer[0];
+ x |= buffer[1] << 8;
+ /* Sign-extension, in case short greater than 16 bits */
+ x |= -(x & 0x8000);
+ }
+ return x;
+}
+
+static long
+r_long(RFILE *p)
+{
+ long x = -1;
+ const unsigned char *buffer;
+
+ buffer = (const unsigned char *) r_string(4, p);
+ if (buffer != NULL) {
+ x = buffer[0];
+ x |= (long)buffer[1] << 8;
+ x |= (long)buffer[2] << 16;
+ x |= (long)buffer[3] << 24;
+#if SIZEOF_LONG > 4
+ /* Sign extension for 64-bit machines */
+ x |= -(x & 0x80000000L);
+#endif
+ }
+ return x;
+}
+
+/* r_long64 deals with the TYPE_INT64 code. */
+static PyObject *
+r_long64(RFILE *p)
+{
+ const unsigned char *buffer = (const unsigned char *) r_string(8, p);
+ if (buffer == NULL) {
+ return NULL;
+ }
+ return _PyLong_FromByteArray(buffer, 8,
+ 1 /* little endian */,
+ 1 /* signed */);
+}
+
+static PyObject *
+r_PyLong(RFILE *p)
+{
+ PyLongObject *ob;
+ long n, size, i;
+ int j, md, shorts_in_top_digit;
+ digit d;
+
+ n = r_long(p);
+ if (PyErr_Occurred())
+ return NULL;
+ if (n == 0)
+ return (PyObject *)_PyLong_New(0);
+ if (n < -SIZE32_MAX || n > SIZE32_MAX) {
+ PyErr_SetString(PyExc_ValueError,
+ "bad marshal data (long size out of range)");
+ return NULL;
+ }
+
+ size = 1 + (Py_ABS(n) - 1) / PyLong_MARSHAL_RATIO;
+ shorts_in_top_digit = 1 + (Py_ABS(n) - 1) % PyLong_MARSHAL_RATIO;
+ ob = _PyLong_New(size);
+ if (ob == NULL)
+ return NULL;
+
+ Py_SET_SIZE(ob, n > 0 ? size : -size);
+
+ for (i = 0; i < size-1; i++) {
+ d = 0;
+ for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
+ md = r_short(p);
+ if (PyErr_Occurred()) {
+ Py_DECREF(ob);
+ return NULL;
+ }
+ if (md < 0 || md > PyLong_MARSHAL_BASE)
+ goto bad_digit;
+ d += (digit)md << j*PyLong_MARSHAL_SHIFT;
+ }
+ ob->ob_digit[i] = d;
+ }
+
+ d = 0;
+ for (j=0; j < shorts_in_top_digit; j++) {
+ md = r_short(p);
+ if (PyErr_Occurred()) {
+ Py_DECREF(ob);
+ return NULL;
+ }
+ if (md < 0 || md > PyLong_MARSHAL_BASE)
+ goto bad_digit;
+ /* topmost marshal digit should be nonzero */
+ if (md == 0 && j == shorts_in_top_digit - 1) {
+ Py_DECREF(ob);
+ PyErr_SetString(PyExc_ValueError,
+ "bad marshal data (unnormalized long data)");
+ return NULL;
+ }
+ d += (digit)md << j*PyLong_MARSHAL_SHIFT;
+ }
+ if (PyErr_Occurred()) {
+ Py_DECREF(ob);
+ return NULL;
+ }
+ /* top digit should be nonzero, else the resulting PyLong won't be
+ normalized */
+ ob->ob_digit[size-1] = d;
+ return (PyObject *)ob;
+ bad_digit:
+ Py_DECREF(ob);
+ PyErr_SetString(PyExc_ValueError,
+ "bad marshal data (digit out of range in long)");
+ return NULL;
+}
+
+static double
+r_float_bin(RFILE *p)
+{
+ const unsigned char *buf = (const unsigned char *) r_string(8, p);
+ if (buf == NULL)
+ return -1;
+ return _PyFloat_Unpack8(buf, 1);
+}
+
+/* Issue #33720: Disable inlining for reducing the C stack consumption
+ on PGO builds. */
+_Py_NO_INLINE static double
+r_float_str(RFILE *p)
+{
+ int n;
+ char buf[256];
+ const char *ptr;
+ n = r_byte(p);
+ if (n == EOF) {
+ PyErr_SetString(PyExc_EOFError,
+ "EOF read where object expected");
+ return -1;
+ }
+ ptr = r_string(n, p);
+ if (ptr == NULL) {
+ return -1;
+ }
+ memcpy(buf, ptr, n);
+ buf[n] = '\0';
+ return PyOS_string_to_double(buf, NULL, NULL);
+}
+
+/* allocate the reflist index for a new object. Return -1 on failure */
+static Py_ssize_t
+r_ref_reserve(int flag, RFILE *p)
+{
+ if (flag) { /* currently only FLAG_REF is defined */
+ Py_ssize_t idx = PyList_GET_SIZE(p->refs);
+ if (idx >= 0x7ffffffe) {
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (index list too large)");
+ return -1;
+ }
+ if (PyList_Append(p->refs, Py_None) < 0)
+ return -1;
+ return idx;
+ } else
+ return 0;
+}
+
+/* insert the new object 'o' to the reflist at previously
+ * allocated index 'idx'.
+ * 'o' can be NULL, in which case nothing is done.
+ * if 'o' was non-NULL, and the function succeeds, 'o' is returned.
+ * if 'o' was non-NULL, and the function fails, 'o' is released and
+ * NULL returned. This simplifies error checking at the call site since
+ * a single test for NULL for the function result is enough.
+ */
+static PyObject *
+r_ref_insert(PyObject *o, Py_ssize_t idx, int flag, RFILE *p)
+{
+ if (o != NULL && flag) { /* currently only FLAG_REF is defined */
+ PyObject *tmp = PyList_GET_ITEM(p->refs, idx);
+ Py_INCREF(o);
+ PyList_SET_ITEM(p->refs, idx, o);
+ Py_DECREF(tmp);
+ }
+ return o;
+}
+
+/* combination of both above, used when an object can be
+ * created whenever it is seen in the file, as opposed to
+ * after having loaded its sub-objects.
+ */
+static PyObject *
+r_ref(PyObject *o, int flag, RFILE *p)
+{
+ assert(flag & FLAG_REF);
+ if (o == NULL)
+ return NULL;
+ if (PyList_Append(p->refs, o) < 0) {
+ Py_DECREF(o); /* release the new object */
+ return NULL;
+ }
+ return o;
+}
+
+static PyObject *
+r_object(RFILE *p)
+{
+ /* NULL is a valid return value, it does not necessarily means that
+ an exception is set. */
+ PyObject *v, *v2;
+ Py_ssize_t idx = 0;
+ long i, n;
+ int type, code = r_byte(p);
+ int flag, is_interned = 0;
+ PyObject *retval = NULL;
+
+ if (code == EOF) {
+ PyErr_SetString(PyExc_EOFError,
+ "EOF read where object expected");
+ return NULL;
+ }
+
+ p->depth++;
+
+ if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
+ p->depth--;
+ PyErr_SetString(PyExc_ValueError, "recursion limit exceeded");
+ return NULL;
+ }
+
+ flag = code & FLAG_REF;
+ type = code & ~FLAG_REF;
+
+#define R_REF(O) do{\
+ if (flag) \
+ O = r_ref(O, flag, p);\
+} while (0)
+
+ switch (type) {
+
+ case TYPE_NULL:
+ break;
+
+ case TYPE_NONE:
+ Py_INCREF(Py_None);
+ retval = Py_None;
+ break;
+
+ case TYPE_STOPITER:
+ Py_INCREF(PyExc_StopIteration);
+ retval = PyExc_StopIteration;
+ break;
+
+ case TYPE_ELLIPSIS:
+ Py_INCREF(Py_Ellipsis);
+ retval = Py_Ellipsis;
+ break;
+
+ case TYPE_FALSE:
+ Py_INCREF(Py_False);
+ retval = Py_False;
+ break;
+
+ case TYPE_TRUE:
+ Py_INCREF(Py_True);
+ retval = Py_True;
+ break;
+
+ case TYPE_INT:
+ n = r_long(p);
+ retval = PyErr_Occurred() ? NULL : PyLong_FromLong(n);
+ R_REF(retval);
+ break;
+
+ case TYPE_INT64:
+ retval = r_long64(p);
+ R_REF(retval);
+ break;
+
+ case TYPE_LONG:
+ retval = r_PyLong(p);
+ R_REF(retval);
+ break;
+
+ case TYPE_FLOAT:
+ {
+ double x = r_float_str(p);
+ if (x == -1.0 && PyErr_Occurred())
+ break;
+ retval = PyFloat_FromDouble(x);
+ R_REF(retval);
+ break;
+ }
+
+ case TYPE_BINARY_FLOAT:
+ {
+ double x = r_float_bin(p);
+ if (x == -1.0 && PyErr_Occurred())
+ break;
+ retval = PyFloat_FromDouble(x);
+ R_REF(retval);
+ break;
+ }
+
+ case TYPE_COMPLEX:
+ {
+ Py_complex c;
+ c.real = r_float_str(p);
+ if (c.real == -1.0 && PyErr_Occurred())
+ break;
+ c.imag = r_float_str(p);
+ if (c.imag == -1.0 && PyErr_Occurred())
+ break;
+ retval = PyComplex_FromCComplex(c);
+ R_REF(retval);
+ break;
+ }
+
+ case TYPE_BINARY_COMPLEX:
+ {
+ Py_complex c;
+ c.real = r_float_bin(p);
+ if (c.real == -1.0 && PyErr_Occurred())
+ break;
+ c.imag = r_float_bin(p);
+ if (c.imag == -1.0 && PyErr_Occurred())
+ break;
+ retval = PyComplex_FromCComplex(c);
+ R_REF(retval);
+ break;
+ }
+
+ case TYPE_STRING:
+ {
+ const char *ptr;
+ n = r_long(p);
+ if (PyErr_Occurred())
+ break;
+ if (n < 0 || n > SIZE32_MAX) {
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (bytes object size out of range)");
+ break;
+ }
+ v = PyBytes_FromStringAndSize((char *)NULL, n);
+ if (v == NULL)
+ break;
+ ptr = r_string(n, p);
+ if (ptr == NULL) {
+ Py_DECREF(v);
+ break;
+ }
+ memcpy(PyBytes_AS_STRING(v), ptr, n);
+ retval = v;
+ R_REF(retval);
+ break;
+ }
+
+ case TYPE_ASCII_INTERNED:
+ is_interned = 1;
+ /* fall through */
+ case TYPE_ASCII:
+ n = r_long(p);
+ if (PyErr_Occurred())
+ break;
+ if (n < 0 || n > SIZE32_MAX) {
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)");
+ break;
+ }
+ goto _read_ascii;
+
+ case TYPE_SHORT_ASCII_INTERNED:
+ is_interned = 1;
+ /* fall through */
+ case TYPE_SHORT_ASCII:
+ n = r_byte(p);
+ if (n == EOF) {
+ PyErr_SetString(PyExc_EOFError,
+ "EOF read where object expected");
+ break;
+ }
+ _read_ascii:
+ {
+ const char *ptr;
+ ptr = r_string(n, p);
+ if (ptr == NULL)
+ break;
+ v = PyUnicode_FromKindAndData(PyUnicode_1BYTE_KIND, ptr, n);
+ if (v == NULL)
+ break;
+ if (is_interned)
+ PyUnicode_InternInPlace(&v);
+ retval = v;
+ R_REF(retval);
+ break;
+ }
+
+ case TYPE_INTERNED:
+ is_interned = 1;
+ /* fall through */
+ case TYPE_UNICODE:
+ {
+ const char *buffer;
+
+ n = r_long(p);
+ if (PyErr_Occurred())
+ break;
+ if (n < 0 || n > SIZE32_MAX) {
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)");
+ break;
+ }
+ if (n != 0) {
+ buffer = r_string(n, p);
+ if (buffer == NULL)
+ break;
+ v = PyUnicode_DecodeUTF8(buffer, n, "surrogatepass");
+ }
+ else {
+ v = PyUnicode_New(0, 0);
+ }
+ if (v == NULL)
+ break;
+ if (is_interned)
+ PyUnicode_InternInPlace(&v);
+ retval = v;
+ R_REF(retval);
+ break;
+ }
+
+ case TYPE_SMALL_TUPLE:
+ n = (unsigned char) r_byte(p);
+ if (PyErr_Occurred())
+ break;
+ goto _read_tuple;
+ case TYPE_TUPLE:
+ n = r_long(p);
+ if (PyErr_Occurred())
+ break;
+ if (n < 0 || n > SIZE32_MAX) {
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (tuple size out of range)");
+ break;
+ }
+ _read_tuple:
+ v = PyTuple_New(n);
+ R_REF(v);
+ if (v == NULL)
+ break;
+
+ for (i = 0; i < n; i++) {
+ v2 = r_object(p);
+ if ( v2 == NULL ) {
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_TypeError,
+ "NULL object in marshal data for tuple");
+ Py_DECREF(v);
+ v = NULL;
+ break;
+ }
+ PyTuple_SET_ITEM(v, i, v2);
+ }
+ retval = v;
+ break;
+
+ case TYPE_LIST:
+ n = r_long(p);
+ if (PyErr_Occurred())
+ break;
+ if (n < 0 || n > SIZE32_MAX) {
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (list size out of range)");
+ break;
+ }
+ v = PyList_New(n);
+ R_REF(v);
+ if (v == NULL)
+ break;
+ for (i = 0; i < n; i++) {
+ v2 = r_object(p);
+ if ( v2 == NULL ) {
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_TypeError,
+ "NULL object in marshal data for list");
+ Py_DECREF(v);
+ v = NULL;
+ break;
+ }
+ PyList_SET_ITEM(v, i, v2);
+ }
+ retval = v;
+ break;
+
+ case TYPE_DICT:
+ v = PyDict_New();
+ R_REF(v);
+ if (v == NULL)
+ break;
+ for (;;) {
+ PyObject *key, *val;
+ key = r_object(p);
+ if (key == NULL)
+ break;
+ val = r_object(p);
+ if (val == NULL) {
+ Py_DECREF(key);
+ break;
+ }
+ if (PyDict_SetItem(v, key, val) < 0) {
+ Py_DECREF(key);
+ Py_DECREF(val);
+ break;
+ }
+ Py_DECREF(key);
+ Py_DECREF(val);
+ }
+ if (PyErr_Occurred()) {
+ Py_DECREF(v);
+ v = NULL;
+ }
+ retval = v;
+ break;
+
+ case TYPE_SET:
+ case TYPE_FROZENSET:
+ n = r_long(p);
+ if (PyErr_Occurred())
+ break;
+ if (n < 0 || n > SIZE32_MAX) {
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (set size out of range)");
+ break;
+ }
+
+ if (n == 0 && type == TYPE_FROZENSET) {
+ /* call frozenset() to get the empty frozenset singleton */
+ v = _PyObject_CallNoArg((PyObject*)&PyFrozenSet_Type);
+ if (v == NULL)
+ break;
+ R_REF(v);
+ retval = v;
+ }
+ else {
+ v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL);
+ if (type == TYPE_SET) {
+ R_REF(v);
+ } else {
+ /* must use delayed registration of frozensets because they must
+ * be init with a refcount of 1
+ */
+ idx = r_ref_reserve(flag, p);
+ if (idx < 0)
+ Py_CLEAR(v); /* signal error */
+ }
+ if (v == NULL)
+ break;
+
+ for (i = 0; i < n; i++) {
+ v2 = r_object(p);
+ if ( v2 == NULL ) {
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_TypeError,
+ "NULL object in marshal data for set");
+ Py_DECREF(v);
+ v = NULL;
+ break;
+ }
+ if (PySet_Add(v, v2) == -1) {
+ Py_DECREF(v);
+ Py_DECREF(v2);
+ v = NULL;
+ break;
+ }
+ Py_DECREF(v2);
+ }
+ if (type != TYPE_SET)
+ v = r_ref_insert(v, idx, flag, p);
+ retval = v;
+ }
+ break;
+
+ case TYPE_CODE:
+ {
+ int argcount;
+ int posonlyargcount;
+ int kwonlyargcount;
+ int nlocals;
+ int stacksize;
+ int flags;
+ PyObject *code = NULL;
+ PyObject *consts = NULL;
+ PyObject *names = NULL;
+ PyObject *varnames = NULL;
+ PyObject *freevars = NULL;
+ PyObject *cellvars = NULL;
+ PyObject *filename = NULL;
+ PyObject *name = NULL;
+ int firstlineno;
+ PyObject *lnotab = NULL;
+
+ idx = r_ref_reserve(flag, p);
+ if (idx < 0)
+ break;
+
+ v = NULL;
+
+ /* XXX ignore long->int overflows for now */
+ argcount = (int)r_long(p);
+ if (PyErr_Occurred())
+ goto code_error;
+ posonlyargcount = (int)r_long(p);
+ if (PyErr_Occurred()) {
+ goto code_error;
+ }
+ kwonlyargcount = (int)r_long(p);
+ if (PyErr_Occurred())
+ goto code_error;
+ nlocals = (int)r_long(p);
+ if (PyErr_Occurred())
+ goto code_error;
+ stacksize = (int)r_long(p);
+ if (PyErr_Occurred())
+ goto code_error;
+ flags = (int)r_long(p);
+ if (PyErr_Occurred())
+ goto code_error;
+ code = r_object(p);
+ if (code == NULL)
+ goto code_error;
+ consts = r_object(p);
+ if (consts == NULL)
+ goto code_error;
+ names = r_object(p);
+ if (names == NULL)
+ goto code_error;
+ varnames = r_object(p);
+ if (varnames == NULL)
+ goto code_error;
+ freevars = r_object(p);
+ if (freevars == NULL)
+ goto code_error;
+ cellvars = r_object(p);
+ if (cellvars == NULL)
+ goto code_error;
+ filename = r_object(p);
+ if (filename == NULL)
+ goto code_error;
+ name = r_object(p);
+ if (name == NULL)
+ goto code_error;
+ firstlineno = (int)r_long(p);
+ if (firstlineno == -1 && PyErr_Occurred())
+ break;
+ lnotab = r_object(p);
+ if (lnotab == NULL)
+ goto code_error;
+
+ v = (PyObject *) PyCode_NewWithPosOnlyArgs(
+ argcount, posonlyargcount, kwonlyargcount,
+ nlocals, stacksize, flags,
+ code, consts, names, varnames,
+ freevars, cellvars, filename, name,
+ firstlineno, lnotab);
+ v = r_ref_insert(v, idx, flag, p);
+
+ code_error:
+ Py_XDECREF(code);
+ Py_XDECREF(consts);
+ Py_XDECREF(names);
+ Py_XDECREF(varnames);
+ Py_XDECREF(freevars);
+ Py_XDECREF(cellvars);
+ Py_XDECREF(filename);
+ Py_XDECREF(name);
+ Py_XDECREF(lnotab);
+ }
+ retval = v;
+ break;
+
+ case TYPE_REF:
+ n = r_long(p);
+ if (n < 0 || n >= PyList_GET_SIZE(p->refs)) {
+ if (n == -1 && PyErr_Occurred())
+ break;
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)");
+ break;
+ }
+ v = PyList_GET_ITEM(p->refs, n);
+ if (v == Py_None) {
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)");
+ break;
+ }
+ Py_INCREF(v);
+ retval = v;
+ break;
+
+ default:
+ /* Bogus data got written, which isn't ideal.
+ This will let you keep working and recover. */
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (unknown type code)");
+ break;
+
+ }
+ p->depth--;
+ return retval;
+}
+
+static PyObject *
+read_object(RFILE *p)
+{
+ PyObject *v;
+ if (PyErr_Occurred()) {
+ fprintf(stderr, "XXX readobject called with exception set\n");
+ return NULL;
+ }
+ if (p->ptr && p->end) {
+ if (PySys_Audit("marshal.loads", "y#", p->ptr, (Py_ssize_t)(p->end - p->ptr)) < 0) {
+ return NULL;
+ }
+ } else if (p->fp || p->readable) {
+ if (PySys_Audit("marshal.load", NULL) < 0) {
+ return NULL;
+ }
+ }
+ v = r_object(p);
+ if (v == NULL && !PyErr_Occurred())
+ PyErr_SetString(PyExc_TypeError, "NULL object in marshal data for object");
+ return v;
+}
+
+int
+PyMarshal_ReadShortFromFile(FILE *fp)
+{
+ RFILE rf;
+ int res;
+ assert(fp);
+ rf.readable = NULL;
+ rf.fp = fp;
+ rf.end = rf.ptr = NULL;
+ rf.buf = NULL;
+ res = r_short(&rf);
+ if (rf.buf != NULL)
+ PyMem_FREE(rf.buf);
+ return res;
+}
+
+long
+PyMarshal_ReadLongFromFile(FILE *fp)
+{
+ RFILE rf;
+ long res;
+ rf.fp = fp;
+ rf.readable = NULL;
+ rf.ptr = rf.end = NULL;
+ rf.buf = NULL;
+ res = r_long(&rf);
+ if (rf.buf != NULL)
+ PyMem_FREE(rf.buf);
+ return res;
+}
+
+/* Return size of file in bytes; < 0 if unknown or INT_MAX if too big */
+static off_t
+getfilesize(FILE *fp)
+{
+ struct _Py_stat_struct st;
+ if (_Py_fstat_noraise(fileno(fp), &st) != 0)
+ return -1;
+#if SIZEOF_OFF_T == 4
+ else if (st.st_size >= INT_MAX)
+ return (off_t)INT_MAX;
+#endif
+ else
+ return (off_t)st.st_size;
+}
+
+/* If we can get the size of the file up-front, and it's reasonably small,
+ * read it in one gulp and delegate to ...FromString() instead. Much quicker
+ * than reading a byte at a time from file; speeds .pyc imports.
+ * CAUTION: since this may read the entire remainder of the file, don't
+ * call it unless you know you're done with the file.
+ */
+PyObject *
+PyMarshal_ReadLastObjectFromFile(FILE *fp)
+{
+/* REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc. */
+#define REASONABLE_FILE_LIMIT (1L << 18)
+ off_t filesize;
+ filesize = getfilesize(fp);
+ if (filesize > 0 && filesize <= REASONABLE_FILE_LIMIT) {
+ char* pBuf = (char *)PyMem_MALLOC(filesize);
+ if (pBuf != NULL) {
+ size_t n = fread(pBuf, 1, (size_t)filesize, fp);
+ PyObject* v = PyMarshal_ReadObjectFromString(pBuf, n);
+ PyMem_FREE(pBuf);
+ return v;
+ }
+
+ }
+ /* We don't have fstat, or we do but the file is larger than
+ * REASONABLE_FILE_LIMIT or malloc failed -- read a byte at a time.
+ */
+ return PyMarshal_ReadObjectFromFile(fp);
+
+#undef REASONABLE_FILE_LIMIT
+}
+
+PyObject *
+PyMarshal_ReadObjectFromFile(FILE *fp)
+{
+ RFILE rf;
+ PyObject *result;
+ rf.fp = fp;
+ rf.readable = NULL;
+ rf.depth = 0;
+ rf.ptr = rf.end = NULL;
+ rf.buf = NULL;
+ rf.refs = PyList_New(0);
+ if (rf.refs == NULL)
+ return NULL;
+ result = read_object(&rf);
+ Py_DECREF(rf.refs);
+ if (rf.buf != NULL)
+ PyMem_FREE(rf.buf);
+ return result;
+}
+
+PyObject *
+PyMarshal_ReadObjectFromString(const char *str, Py_ssize_t len)
+{
+ RFILE rf;
+ PyObject *result;
+ rf.fp = NULL;
+ rf.readable = NULL;
+ rf.ptr = str;
+ rf.end = str + len;
+ rf.buf = NULL;
+ rf.depth = 0;
+ rf.refs = PyList_New(0);
+ if (rf.refs == NULL)
+ return NULL;
+ result = read_object(&rf);
+ Py_DECREF(rf.refs);
+ if (rf.buf != NULL)
+ PyMem_FREE(rf.buf);
+ return result;
+}
+
+PyObject *
+PyMarshal_WriteObjectToString(PyObject *x, int version)
+{
+ WFILE wf;
+
+ if (PySys_Audit("marshal.dumps", "Oi", x, version) < 0) {
+ return NULL;
+ }
+ memset(&wf, 0, sizeof(wf));
+ wf.str = PyBytes_FromStringAndSize((char *)NULL, 50);
+ if (wf.str == NULL)
+ return NULL;
+ wf.ptr = wf.buf = PyBytes_AS_STRING(wf.str);
+ wf.end = wf.ptr + PyBytes_GET_SIZE(wf.str);
+ wf.error = WFERR_OK;
+ wf.version = version;
+ if (w_init_refs(&wf, version)) {
+ Py_DECREF(wf.str);
+ return NULL;
+ }
+ w_object(x, &wf);
+ w_clear_refs(&wf);
+ if (wf.str != NULL) {
+ const char *base = PyBytes_AS_STRING(wf.str);
+ if (_PyBytes_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)) < 0)
+ return NULL;
+ }
+ if (wf.error != WFERR_OK) {
+ Py_XDECREF(wf.str);
+ if (wf.error == WFERR_NOMEMORY)
+ PyErr_NoMemory();
+ else
+ PyErr_SetString(PyExc_ValueError,
+ (wf.error==WFERR_UNMARSHALLABLE)?"unmarshallable object"
+ :"object too deeply nested to marshal");
+ return NULL;
+ }
+ return wf.str;
+}
+
+/* And an interface for Python programs... */
+/*[clinic input]
+marshal.dump
+
+ value: object
+ Must be a supported type.
+ file: object
+ Must be a writeable binary file.
+ version: int(c_default="Py_MARSHAL_VERSION") = version
+ Indicates the data format that dump should use.
+ /
+
+Write the value on the open file.
+
+If the value has (or contains an object that has) an unsupported type, a
+ValueError exception is raised - but garbage data will also be written
+to the file. The object will not be properly read back by load().
+[clinic start generated code]*/
+
+static PyObject *
+marshal_dump_impl(PyObject *module, PyObject *value, PyObject *file,
+ int version)
+/*[clinic end generated code: output=aaee62c7028a7cb2 input=6c7a3c23c6fef556]*/
+{
+ /* XXX Quick hack -- need to do this differently */
+ PyObject *s;
+ PyObject *res;
+ _Py_IDENTIFIER(write);
+
+ s = PyMarshal_WriteObjectToString(value, version);
+ if (s == NULL)
+ return NULL;
+ res = _PyObject_CallMethodIdOneArg(file, &PyId_write, s);
+ Py_DECREF(s);
+ return res;
+}
+
+/*[clinic input]
+marshal.load
+
+ file: object
+ Must be readable binary file.
+ /
+
+Read one value from the open file and return it.
+
+If no valid value is read (e.g. because the data has a different Python
+version's incompatible marshal format), raise EOFError, ValueError or
+TypeError.
+
+Note: If an object containing an unsupported type was marshalled with
+dump(), load() will substitute None for the unmarshallable type.
+[clinic start generated code]*/
+
+static PyObject *
+marshal_load(PyObject *module, PyObject *file)
+/*[clinic end generated code: output=f8e5c33233566344 input=c85c2b594cd8124a]*/
+{
+ PyObject *data, *result;
+ _Py_IDENTIFIER(read);
+ RFILE rf;
+
+ /*
+ * Make a call to the read method, but read zero bytes.
+ * This is to ensure that the object passed in at least
+ * has a read method which returns bytes.
+ * This can be removed if we guarantee good error handling
+ * for r_string()
+ */
+ data = _PyObject_CallMethodId(file, &PyId_read, "i", 0);
+ if (data == NULL)
+ return NULL;
+ if (!PyBytes_Check(data)) {
+ PyErr_Format(PyExc_TypeError,
+ "file.read() returned not bytes but %.100s",
+ Py_TYPE(data)->tp_name);
+ result = NULL;
+ }
+ else {
+ rf.depth = 0;
+ rf.fp = NULL;
+ rf.readable = file;
+ rf.ptr = rf.end = NULL;
+ rf.buf = NULL;
+ if ((rf.refs = PyList_New(0)) != NULL) {
+ result = read_object(&rf);
+ Py_DECREF(rf.refs);
+ if (rf.buf != NULL)
+ PyMem_FREE(rf.buf);
+ } else
+ result = NULL;
+ }
+ Py_DECREF(data);
+ return result;
+}
+
+/*[clinic input]
+marshal.dumps
+
+ value: object
+ Must be a supported type.
+ version: int(c_default="Py_MARSHAL_VERSION") = version
+ Indicates the data format that dumps should use.
+ /
+
+Return the bytes object that would be written to a file by dump(value, file).
+
+Raise a ValueError exception if value has (or contains an object that has) an
+unsupported type.
+[clinic start generated code]*/
+
+static PyObject *
+marshal_dumps_impl(PyObject *module, PyObject *value, int version)
+/*[clinic end generated code: output=9c200f98d7256cad input=a2139ea8608e9b27]*/
+{
+ return PyMarshal_WriteObjectToString(value, version);
+}
+
+/*[clinic input]
+marshal.loads
+
+ bytes: Py_buffer
+ /
+
+Convert the bytes-like object to a value.
+
+If no valid value is found, raise EOFError, ValueError or TypeError. Extra
+bytes in the input are ignored.
+[clinic start generated code]*/
+
+static PyObject *
+marshal_loads_impl(PyObject *module, Py_buffer *bytes)
+/*[clinic end generated code: output=9fc65985c93d1bb1 input=6f426518459c8495]*/
+{
+ RFILE rf;
+ char *s = bytes->buf;
+ Py_ssize_t n = bytes->len;
+ PyObject* result;
+ rf.fp = NULL;
+ rf.readable = NULL;
+ rf.ptr = s;
+ rf.end = s + n;
+ rf.depth = 0;
+ if ((rf.refs = PyList_New(0)) == NULL)
+ return NULL;
+ result = read_object(&rf);
+ Py_DECREF(rf.refs);
+ return result;
+}
+
+static PyMethodDef marshal_methods[] = {
+ MARSHAL_DUMP_METHODDEF
+ MARSHAL_LOAD_METHODDEF
+ MARSHAL_DUMPS_METHODDEF
+ MARSHAL_LOADS_METHODDEF
+ {NULL, NULL} /* sentinel */
+};
+
+
+PyDoc_STRVAR(module_doc,
+"This module contains functions that can read and write Python values in\n\
+a binary format. The format is specific to Python, but independent of\n\
+machine architecture issues.\n\
+\n\
+Not all Python object types are supported; in general, only objects\n\
+whose value is independent from a particular invocation of Python can be\n\
+written and read by this module. The following types are supported:\n\
+None, integers, floating point numbers, strings, bytes, bytearrays,\n\
+tuples, lists, sets, dictionaries, and code objects, where it\n\
+should be understood that tuples, lists and dictionaries are only\n\
+supported as long as the values contained therein are themselves\n\
+supported; and recursive lists and dictionaries should not be written\n\
+(they will cause infinite loops).\n\
+\n\
+Variables:\n\
+\n\
+version -- indicates the format that the module uses. Version 0 is the\n\
+ historical format, version 1 shares interned strings and version 2\n\
+ uses a binary format for floating point numbers.\n\
+ Version 3 shares common object references (New in version 3.4).\n\
+\n\
+Functions:\n\
+\n\
+dump() -- write value to a file\n\
+load() -- read value from a file\n\
+dumps() -- marshal value as a bytes object\n\
+loads() -- read value from a bytes-like object");
+
+
+
+static struct PyModuleDef marshalmodule = {
+ PyModuleDef_HEAD_INIT,
+ "marshal",
+ module_doc,
+ 0,
+ marshal_methods,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+PyMODINIT_FUNC
+PyMarshal_Init(void)
+{
+ PyObject *mod = PyModule_Create(&marshalmodule);
+ if (mod == NULL)
+ return NULL;
+ if (PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION) < 0) {
+ Py_DECREF(mod);
+ return NULL;
+ }
+ return mod;
+}
diff --git a/contrib/tools/python3/src/Python/modsupport.c b/contrib/tools/python3/src/Python/modsupport.c
new file mode 100644
index 00000000000..13482c65083
--- /dev/null
+++ b/contrib/tools/python3/src/Python/modsupport.c
@@ -0,0 +1,703 @@
+
+/* Module support implementation */
+
+#include "Python.h"
+#include "pycore_abstract.h" // _PyIndex_Check()
+
+#define FLAG_SIZE_T 1
+typedef double va_double;
+
+static PyObject *va_build_value(const char *, va_list, int);
+static PyObject **va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len, const char *, va_list, int, Py_ssize_t*);
+
+/* Package context -- the full module name for package imports */
+const char *_Py_PackageContext = NULL;
+
+
+int
+_Py_convert_optional_to_ssize_t(PyObject *obj, void *result)
+{
+ Py_ssize_t limit;
+ if (obj == Py_None) {
+ return 1;
+ }
+ else if (_PyIndex_Check(obj)) {
+ limit = PyNumber_AsSsize_t(obj, PyExc_OverflowError);
+ if (limit == -1 && PyErr_Occurred()) {
+ return 0;
+ }
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "argument should be integer or None, not '%.200s'",
+ Py_TYPE(obj)->tp_name);
+ return 0;
+ }
+ *((Py_ssize_t *)result) = limit;
+ return 1;
+}
+
+
+/* Helper for mkvalue() to scan the length of a format */
+
+static Py_ssize_t
+countformat(const char *format, char endchar)
+{
+ Py_ssize_t count = 0;
+ int level = 0;
+ while (level > 0 || *format != endchar) {
+ switch (*format) {
+ case '\0':
+ /* Premature end */
+ PyErr_SetString(PyExc_SystemError,
+ "unmatched paren in format");
+ return -1;
+ case '(':
+ case '[':
+ case '{':
+ if (level == 0) {
+ count++;
+ }
+ level++;
+ break;
+ case ')':
+ case ']':
+ case '}':
+ level--;
+ break;
+ case '#':
+ case '&':
+ case ',':
+ case ':':
+ case ' ':
+ case '\t':
+ break;
+ default:
+ if (level == 0) {
+ count++;
+ }
+ }
+ format++;
+ }
+ return count;
+}
+
+
+/* Generic function to create a value -- the inverse of getargs() */
+/* After an original idea and first implementation by Steven Miale */
+
+static PyObject *do_mktuple(const char**, va_list *, char, Py_ssize_t, int);
+static int do_mkstack(PyObject **, const char**, va_list *, char, Py_ssize_t, int);
+static PyObject *do_mklist(const char**, va_list *, char, Py_ssize_t, int);
+static PyObject *do_mkdict(const char**, va_list *, char, Py_ssize_t, int);
+static PyObject *do_mkvalue(const char**, va_list *, int);
+
+
+static void
+do_ignore(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags)
+{
+ PyObject *v;
+ Py_ssize_t i;
+ assert(PyErr_Occurred());
+ v = PyTuple_New(n);
+ for (i = 0; i < n; i++) {
+ PyObject *exception, *value, *tb, *w;
+
+ PyErr_Fetch(&exception, &value, &tb);
+ w = do_mkvalue(p_format, p_va, flags);
+ PyErr_Restore(exception, value, tb);
+ if (w != NULL) {
+ if (v != NULL) {
+ PyTuple_SET_ITEM(v, i, w);
+ }
+ else {
+ Py_DECREF(w);
+ }
+ }
+ }
+ Py_XDECREF(v);
+ if (**p_format != endchar) {
+ PyErr_SetString(PyExc_SystemError,
+ "Unmatched paren in format");
+ return;
+ }
+ if (endchar) {
+ ++*p_format;
+ }
+}
+
+static PyObject *
+do_mkdict(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags)
+{
+ PyObject *d;
+ Py_ssize_t i;
+ if (n < 0)
+ return NULL;
+ if (n % 2) {
+ PyErr_SetString(PyExc_SystemError,
+ "Bad dict format");
+ do_ignore(p_format, p_va, endchar, n, flags);
+ return NULL;
+ }
+ /* Note that we can't bail immediately on error as this will leak
+ refcounts on any 'N' arguments. */
+ if ((d = PyDict_New()) == NULL) {
+ do_ignore(p_format, p_va, endchar, n, flags);
+ return NULL;
+ }
+ for (i = 0; i < n; i+= 2) {
+ PyObject *k, *v;
+
+ k = do_mkvalue(p_format, p_va, flags);
+ if (k == NULL) {
+ do_ignore(p_format, p_va, endchar, n - i - 1, flags);
+ Py_DECREF(d);
+ return NULL;
+ }
+ v = do_mkvalue(p_format, p_va, flags);
+ if (v == NULL || PyDict_SetItem(d, k, v) < 0) {
+ do_ignore(p_format, p_va, endchar, n - i - 2, flags);
+ Py_DECREF(k);
+ Py_XDECREF(v);
+ Py_DECREF(d);
+ return NULL;
+ }
+ Py_DECREF(k);
+ Py_DECREF(v);
+ }
+ if (**p_format != endchar) {
+ Py_DECREF(d);
+ PyErr_SetString(PyExc_SystemError,
+ "Unmatched paren in format");
+ return NULL;
+ }
+ if (endchar)
+ ++*p_format;
+ return d;
+}
+
+static PyObject *
+do_mklist(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags)
+{
+ PyObject *v;
+ Py_ssize_t i;
+ if (n < 0)
+ return NULL;
+ /* Note that we can't bail immediately on error as this will leak
+ refcounts on any 'N' arguments. */
+ v = PyList_New(n);
+ if (v == NULL) {
+ do_ignore(p_format, p_va, endchar, n, flags);
+ return NULL;
+ }
+ for (i = 0; i < n; i++) {
+ PyObject *w = do_mkvalue(p_format, p_va, flags);
+ if (w == NULL) {
+ do_ignore(p_format, p_va, endchar, n - i - 1, flags);
+ Py_DECREF(v);
+ return NULL;
+ }
+ PyList_SET_ITEM(v, i, w);
+ }
+ if (**p_format != endchar) {
+ Py_DECREF(v);
+ PyErr_SetString(PyExc_SystemError,
+ "Unmatched paren in format");
+ return NULL;
+ }
+ if (endchar)
+ ++*p_format;
+ return v;
+}
+
+static int
+do_mkstack(PyObject **stack, const char **p_format, va_list *p_va,
+ char endchar, Py_ssize_t n, int flags)
+{
+ Py_ssize_t i;
+
+ if (n < 0) {
+ return -1;
+ }
+ /* Note that we can't bail immediately on error as this will leak
+ refcounts on any 'N' arguments. */
+ for (i = 0; i < n; i++) {
+ PyObject *w = do_mkvalue(p_format, p_va, flags);
+ if (w == NULL) {
+ do_ignore(p_format, p_va, endchar, n - i - 1, flags);
+ goto error;
+ }
+ stack[i] = w;
+ }
+ if (**p_format != endchar) {
+ PyErr_SetString(PyExc_SystemError,
+ "Unmatched paren in format");
+ goto error;
+ }
+ if (endchar) {
+ ++*p_format;
+ }
+ return 0;
+
+error:
+ n = i;
+ for (i=0; i < n; i++) {
+ Py_DECREF(stack[i]);
+ }
+ return -1;
+}
+
+static PyObject *
+do_mktuple(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags)
+{
+ PyObject *v;
+ Py_ssize_t i;
+ if (n < 0)
+ return NULL;
+ /* Note that we can't bail immediately on error as this will leak
+ refcounts on any 'N' arguments. */
+ if ((v = PyTuple_New(n)) == NULL) {
+ do_ignore(p_format, p_va, endchar, n, flags);
+ return NULL;
+ }
+ for (i = 0; i < n; i++) {
+ PyObject *w = do_mkvalue(p_format, p_va, flags);
+ if (w == NULL) {
+ do_ignore(p_format, p_va, endchar, n - i - 1, flags);
+ Py_DECREF(v);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(v, i, w);
+ }
+ if (**p_format != endchar) {
+ Py_DECREF(v);
+ PyErr_SetString(PyExc_SystemError,
+ "Unmatched paren in format");
+ return NULL;
+ }
+ if (endchar)
+ ++*p_format;
+ return v;
+}
+
+static PyObject *
+do_mkvalue(const char **p_format, va_list *p_va, int flags)
+{
+ for (;;) {
+ switch (*(*p_format)++) {
+ case '(':
+ return do_mktuple(p_format, p_va, ')',
+ countformat(*p_format, ')'), flags);
+
+ case '[':
+ return do_mklist(p_format, p_va, ']',
+ countformat(*p_format, ']'), flags);
+
+ case '{':
+ return do_mkdict(p_format, p_va, '}',
+ countformat(*p_format, '}'), flags);
+
+ case 'b':
+ case 'B':
+ case 'h':
+ case 'i':
+ return PyLong_FromLong((long)va_arg(*p_va, int));
+
+ case 'H':
+ return PyLong_FromLong((long)va_arg(*p_va, unsigned int));
+
+ case 'I':
+ {
+ unsigned int n;
+ n = va_arg(*p_va, unsigned int);
+ return PyLong_FromUnsignedLong(n);
+ }
+
+ case 'n':
+#if SIZEOF_SIZE_T!=SIZEOF_LONG
+ return PyLong_FromSsize_t(va_arg(*p_va, Py_ssize_t));
+#endif
+ /* Fall through from 'n' to 'l' if Py_ssize_t is long */
+ case 'l':
+ return PyLong_FromLong(va_arg(*p_va, long));
+
+ case 'k':
+ {
+ unsigned long n;
+ n = va_arg(*p_va, unsigned long);
+ return PyLong_FromUnsignedLong(n);
+ }
+
+ case 'L':
+ return PyLong_FromLongLong((long long)va_arg(*p_va, long long));
+
+ case 'K':
+ return PyLong_FromUnsignedLongLong((long long)va_arg(*p_va, unsigned long long));
+
+ case 'u':
+ {
+ PyObject *v;
+ Py_UNICODE *u = va_arg(*p_va, Py_UNICODE *);
+ Py_ssize_t n;
+ if (**p_format == '#') {
+ ++*p_format;
+ if (flags & FLAG_SIZE_T)
+ n = va_arg(*p_va, Py_ssize_t);
+ else {
+ n = va_arg(*p_va, int);
+ if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) {
+ return NULL;
+ }
+ }
+ }
+ else
+ n = -1;
+ if (u == NULL) {
+ v = Py_None;
+ Py_INCREF(v);
+ }
+ else {
+ if (n < 0)
+ n = wcslen(u);
+ v = PyUnicode_FromWideChar(u, n);
+ }
+ return v;
+ }
+ case 'f':
+ case 'd':
+ return PyFloat_FromDouble(
+ (double)va_arg(*p_va, va_double));
+
+ case 'D':
+ return PyComplex_FromCComplex(
+ *((Py_complex *)va_arg(*p_va, Py_complex *)));
+
+ case 'c':
+ {
+ char p[1];
+ p[0] = (char)va_arg(*p_va, int);
+ return PyBytes_FromStringAndSize(p, 1);
+ }
+ case 'C':
+ {
+ int i = va_arg(*p_va, int);
+ return PyUnicode_FromOrdinal(i);
+ }
+
+ case 's':
+ case 'z':
+ case 'U': /* XXX deprecated alias */
+ {
+ PyObject *v;
+ const char *str = va_arg(*p_va, const char *);
+ Py_ssize_t n;
+ if (**p_format == '#') {
+ ++*p_format;
+ if (flags & FLAG_SIZE_T)
+ n = va_arg(*p_va, Py_ssize_t);
+ else {
+ n = va_arg(*p_va, int);
+ if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) {
+ return NULL;
+ }
+ }
+ }
+ else
+ n = -1;
+ if (str == NULL) {
+ v = Py_None;
+ Py_INCREF(v);
+ }
+ else {
+ if (n < 0) {
+ size_t m = strlen(str);
+ if (m > PY_SSIZE_T_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "string too long for Python string");
+ return NULL;
+ }
+ n = (Py_ssize_t)m;
+ }
+ v = PyUnicode_FromStringAndSize(str, n);
+ }
+ return v;
+ }
+
+ case 'y':
+ {
+ PyObject *v;
+ const char *str = va_arg(*p_va, const char *);
+ Py_ssize_t n;
+ if (**p_format == '#') {
+ ++*p_format;
+ if (flags & FLAG_SIZE_T)
+ n = va_arg(*p_va, Py_ssize_t);
+ else {
+ n = va_arg(*p_va, int);
+ if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) {
+ return NULL;
+ }
+ }
+ }
+ else
+ n = -1;
+ if (str == NULL) {
+ v = Py_None;
+ Py_INCREF(v);
+ }
+ else {
+ if (n < 0) {
+ size_t m = strlen(str);
+ if (m > PY_SSIZE_T_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "string too long for Python bytes");
+ return NULL;
+ }
+ n = (Py_ssize_t)m;
+ }
+ v = PyBytes_FromStringAndSize(str, n);
+ }
+ return v;
+ }
+
+ case 'N':
+ case 'S':
+ case 'O':
+ if (**p_format == '&') {
+ typedef PyObject *(*converter)(void *);
+ converter func = va_arg(*p_va, converter);
+ void *arg = va_arg(*p_va, void *);
+ ++*p_format;
+ return (*func)(arg);
+ }
+ else {
+ PyObject *v;
+ v = va_arg(*p_va, PyObject *);
+ if (v != NULL) {
+ if (*(*p_format - 1) != 'N')
+ Py_INCREF(v);
+ }
+ else if (!PyErr_Occurred())
+ /* If a NULL was passed
+ * because a call that should
+ * have constructed a value
+ * failed, that's OK, and we
+ * pass the error on; but if
+ * no error occurred it's not
+ * clear that the caller knew
+ * what she was doing. */
+ PyErr_SetString(PyExc_SystemError,
+ "NULL object passed to Py_BuildValue");
+ return v;
+ }
+
+ case ':':
+ case ',':
+ case ' ':
+ case '\t':
+ break;
+
+ default:
+ PyErr_SetString(PyExc_SystemError,
+ "bad format char passed to Py_BuildValue");
+ return NULL;
+
+ }
+ }
+}
+
+
+PyObject *
+Py_BuildValue(const char *format, ...)
+{
+ va_list va;
+ PyObject* retval;
+ va_start(va, format);
+ retval = va_build_value(format, va, 0);
+ va_end(va);
+ return retval;
+}
+
+PyObject *
+_Py_BuildValue_SizeT(const char *format, ...)
+{
+ va_list va;
+ PyObject* retval;
+ va_start(va, format);
+ retval = va_build_value(format, va, FLAG_SIZE_T);
+ va_end(va);
+ return retval;
+}
+
+PyObject *
+Py_VaBuildValue(const char *format, va_list va)
+{
+ return va_build_value(format, va, 0);
+}
+
+PyObject *
+_Py_VaBuildValue_SizeT(const char *format, va_list va)
+{
+ return va_build_value(format, va, FLAG_SIZE_T);
+}
+
+static PyObject *
+va_build_value(const char *format, va_list va, int flags)
+{
+ const char *f = format;
+ Py_ssize_t n = countformat(f, '\0');
+ va_list lva;
+ PyObject *retval;
+
+ if (n < 0)
+ return NULL;
+ if (n == 0) {
+ Py_RETURN_NONE;
+ }
+ va_copy(lva, va);
+ if (n == 1) {
+ retval = do_mkvalue(&f, &lva, flags);
+ } else {
+ retval = do_mktuple(&f, &lva, '\0', n, flags);
+ }
+ va_end(lva);
+ return retval;
+}
+
+PyObject **
+_Py_VaBuildStack(PyObject **small_stack, Py_ssize_t small_stack_len,
+ const char *format, va_list va, Py_ssize_t *p_nargs)
+{
+ return va_build_stack(small_stack, small_stack_len, format, va, 0, p_nargs);
+}
+
+PyObject **
+_Py_VaBuildStack_SizeT(PyObject **small_stack, Py_ssize_t small_stack_len,
+ const char *format, va_list va, Py_ssize_t *p_nargs)
+{
+ return va_build_stack(small_stack, small_stack_len, format, va, FLAG_SIZE_T, p_nargs);
+}
+
+static PyObject **
+va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len,
+ const char *format, va_list va, int flags, Py_ssize_t *p_nargs)
+{
+ const char *f;
+ Py_ssize_t n;
+ va_list lva;
+ PyObject **stack;
+ int res;
+
+ n = countformat(format, '\0');
+ if (n < 0) {
+ *p_nargs = 0;
+ return NULL;
+ }
+
+ if (n == 0) {
+ *p_nargs = 0;
+ return small_stack;
+ }
+
+ if (n <= small_stack_len) {
+ stack = small_stack;
+ }
+ else {
+ stack = PyMem_Malloc(n * sizeof(stack[0]));
+ if (stack == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ }
+
+ va_copy(lva, va);
+ f = format;
+ res = do_mkstack(stack, &f, &lva, '\0', n, flags);
+ va_end(lva);
+
+ if (res < 0) {
+ if (stack != small_stack) {
+ PyMem_Free(stack);
+ }
+ return NULL;
+ }
+
+ *p_nargs = n;
+ return stack;
+}
+
+
+int
+PyModule_AddObject(PyObject *m, const char *name, PyObject *o)
+{
+ PyObject *dict;
+ if (!PyModule_Check(m)) {
+ PyErr_SetString(PyExc_TypeError,
+ "PyModule_AddObject() needs module as first arg");
+ return -1;
+ }
+ if (!o) {
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_TypeError,
+ "PyModule_AddObject() needs non-NULL value");
+ return -1;
+ }
+
+ dict = PyModule_GetDict(m);
+ if (dict == NULL) {
+ /* Internal error -- modules must have a dict! */
+ PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__",
+ PyModule_GetName(m));
+ return -1;
+ }
+ if (PyDict_SetItemString(dict, name, o))
+ return -1;
+ Py_DECREF(o);
+ return 0;
+}
+
+int
+PyModule_AddIntConstant(PyObject *m, const char *name, long value)
+{
+ PyObject *o = PyLong_FromLong(value);
+ if (!o)
+ return -1;
+ if (PyModule_AddObject(m, name, o) == 0)
+ return 0;
+ Py_DECREF(o);
+ return -1;
+}
+
+int
+PyModule_AddStringConstant(PyObject *m, const char *name, const char *value)
+{
+ PyObject *o = PyUnicode_FromString(value);
+ if (!o)
+ return -1;
+ if (PyModule_AddObject(m, name, o) == 0)
+ return 0;
+ Py_DECREF(o);
+ return -1;
+}
+
+int
+PyModule_AddType(PyObject *module, PyTypeObject *type)
+{
+ if (PyType_Ready(type) < 0) {
+ return -1;
+ }
+
+ const char *name = _PyType_Name(type);
+ assert(name != NULL);
+
+ Py_INCREF(type);
+ if (PyModule_AddObject(module, name, (PyObject *)type) < 0) {
+ Py_DECREF(type);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/contrib/tools/python3/src/Python/mysnprintf.c b/contrib/tools/python3/src/Python/mysnprintf.c
new file mode 100644
index 00000000000..458ca14d5c6
--- /dev/null
+++ b/contrib/tools/python3/src/Python/mysnprintf.c
@@ -0,0 +1,111 @@
+#include "Python.h"
+
+/* snprintf() and vsnprintf() wrappers.
+
+ If the platform has vsnprintf, we use it, else we
+ emulate it in a half-hearted way. Even if the platform has it, we wrap
+ it because platforms differ in what vsnprintf does in case the buffer
+ is too small: C99 behavior is to return the number of characters that
+ would have been written had the buffer not been too small, and to set
+ the last byte of the buffer to \0. At least MS _vsnprintf returns a
+ negative value instead, and fills the entire buffer with non-\0 data.
+
+ The wrappers ensure that str[size-1] is always \0 upon return.
+
+ PyOS_snprintf and PyOS_vsnprintf never write more than size bytes
+ (including the trailing '\0') into str.
+
+ If the platform doesn't have vsnprintf, and the buffer size needed to
+ avoid truncation exceeds size by more than 512, Python aborts with a
+ Py_FatalError.
+
+ Return value (rv):
+
+ When 0 <= rv < size, the output conversion was unexceptional, and
+ rv characters were written to str (excluding a trailing \0 byte at
+ str[rv]).
+
+ When rv >= size, output conversion was truncated, and a buffer of
+ size rv+1 would have been needed to avoid truncation. str[size-1]
+ is \0 in this case.
+
+ When rv < 0, "something bad happened". str[size-1] is \0 in this
+ case too, but the rest of str is unreliable. It could be that
+ an error in format codes was detected by libc, or on platforms
+ with a non-C99 vsnprintf simply that the buffer wasn't big enough
+ to avoid truncation, or on platforms without any vsnprintf that
+ PyMem_Malloc couldn't obtain space for a temp buffer.
+
+ CAUTION: Unlike C99, str != NULL and size > 0 are required.
+*/
+
+int
+PyOS_snprintf(char *str, size_t size, const char *format, ...)
+{
+ int rc;
+ va_list va;
+
+ va_start(va, format);
+ rc = PyOS_vsnprintf(str, size, format, va);
+ va_end(va);
+ return rc;
+}
+
+int
+PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)
+{
+ assert(str != NULL);
+ assert(size > 0);
+ assert(format != NULL);
+
+ int len; /* # bytes written, excluding \0 */
+#if defined(_MSC_VER) || defined(HAVE_SNPRINTF)
+# define _PyOS_vsnprintf_EXTRA_SPACE 1
+#else
+# define _PyOS_vsnprintf_EXTRA_SPACE 512
+ char *buffer;
+#endif
+ /* We take a size_t as input but return an int. Sanity check
+ * our input so that it won't cause an overflow in the
+ * vsnprintf return value or the buffer malloc size. */
+ if (size > INT_MAX - _PyOS_vsnprintf_EXTRA_SPACE) {
+ len = -666;
+ goto Done;
+ }
+
+#if defined(_MSC_VER)
+ len = _vsnprintf(str, size, format, va);
+#elif defined(HAVE_SNPRINTF)
+ len = vsnprintf(str, size, format, va);
+#else
+ /* Emulate vsnprintf(). */
+ buffer = PyMem_MALLOC(size + _PyOS_vsnprintf_EXTRA_SPACE);
+ if (buffer == NULL) {
+ len = -666;
+ goto Done;
+ }
+
+ len = vsprintf(buffer, format, va);
+ if (len < 0) {
+ /* ignore the error */;
+ }
+ else if ((size_t)len >= size + _PyOS_vsnprintf_EXTRA_SPACE) {
+ _Py_FatalErrorFunc(__func__, "Buffer overflow");
+ }
+ else {
+ const size_t to_copy = (size_t)len < size ?
+ (size_t)len : size - 1;
+ assert(to_copy < size);
+ memcpy(str, buffer, to_copy);
+ str[to_copy] = '\0';
+ }
+ PyMem_FREE(buffer);
+#endif
+
+Done:
+ if (size > 0) {
+ str[size-1] = '\0';
+ }
+ return len;
+#undef _PyOS_vsnprintf_EXTRA_SPACE
+}
diff --git a/contrib/tools/python3/src/Python/mystrtoul.c b/contrib/tools/python3/src/Python/mystrtoul.c
new file mode 100644
index 00000000000..19fa57aa144
--- /dev/null
+++ b/contrib/tools/python3/src/Python/mystrtoul.c
@@ -0,0 +1,291 @@
+
+#include "Python.h"
+
+#if defined(__sgi) && !defined(_SGI_MP_SOURCE)
+#define _SGI_MP_SOURCE
+#endif
+
+/* strtol and strtoul, renamed to avoid conflicts */
+
+
+#include <ctype.h>
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+/* Static overflow check values for bases 2 through 36.
+ * smallmax[base] is the largest unsigned long i such that
+ * i * base doesn't overflow unsigned long.
+ */
+static const unsigned long smallmax[] = {
+ 0, /* bases 0 and 1 are invalid */
+ 0,
+ ULONG_MAX / 2,
+ ULONG_MAX / 3,
+ ULONG_MAX / 4,
+ ULONG_MAX / 5,
+ ULONG_MAX / 6,
+ ULONG_MAX / 7,
+ ULONG_MAX / 8,
+ ULONG_MAX / 9,
+ ULONG_MAX / 10,
+ ULONG_MAX / 11,
+ ULONG_MAX / 12,
+ ULONG_MAX / 13,
+ ULONG_MAX / 14,
+ ULONG_MAX / 15,
+ ULONG_MAX / 16,
+ ULONG_MAX / 17,
+ ULONG_MAX / 18,
+ ULONG_MAX / 19,
+ ULONG_MAX / 20,
+ ULONG_MAX / 21,
+ ULONG_MAX / 22,
+ ULONG_MAX / 23,
+ ULONG_MAX / 24,
+ ULONG_MAX / 25,
+ ULONG_MAX / 26,
+ ULONG_MAX / 27,
+ ULONG_MAX / 28,
+ ULONG_MAX / 29,
+ ULONG_MAX / 30,
+ ULONG_MAX / 31,
+ ULONG_MAX / 32,
+ ULONG_MAX / 33,
+ ULONG_MAX / 34,
+ ULONG_MAX / 35,
+ ULONG_MAX / 36,
+};
+
+/* maximum digits that can't ever overflow for bases 2 through 36,
+ * calculated by [int(math.floor(math.log(2**32, i))) for i in range(2, 37)].
+ * Note that this is pessimistic if sizeof(long) > 4.
+ */
+#if SIZEOF_LONG == 4
+static const int digitlimit[] = {
+ 0, 0, 32, 20, 16, 13, 12, 11, 10, 10, /* 0 - 9 */
+ 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, /* 10 - 19 */
+ 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, /* 20 - 29 */
+ 6, 6, 6, 6, 6, 6, 6}; /* 30 - 36 */
+#elif SIZEOF_LONG == 8
+/* [int(math.floor(math.log(2**64, i))) for i in range(2, 37)] */
+static const int digitlimit[] = {
+ 0, 0, 64, 40, 32, 27, 24, 22, 21, 20, /* 0 - 9 */
+ 19, 18, 17, 17, 16, 16, 16, 15, 15, 15, /* 10 - 19 */
+ 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, /* 20 - 29 */
+ 13, 12, 12, 12, 12, 12, 12}; /* 30 - 36 */
+#else
+#error "Need table for SIZEOF_LONG"
+#endif
+
+/*
+** strtoul
+** This is a general purpose routine for converting
+** an ascii string to an integer in an arbitrary base.
+** Leading white space is ignored. If 'base' is zero
+** it looks for a leading 0b, 0o or 0x to tell which
+** base. If these are absent it defaults to 10.
+** Base must be 0 or between 2 and 36 (inclusive).
+** If 'ptr' is non-NULL it will contain a pointer to
+** the end of the scan.
+** Errors due to bad pointers will probably result in
+** exceptions - we don't check for them.
+*/
+unsigned long
+PyOS_strtoul(const char *str, char **ptr, int base)
+{
+ unsigned long result = 0; /* return value of the function */
+ int c; /* current input character */
+ int ovlimit; /* required digits to overflow */
+
+ /* skip leading white space */
+ while (*str && Py_ISSPACE(*str))
+ ++str;
+
+ /* check for leading 0b, 0o or 0x for auto-base or base 16 */
+ switch (base) {
+ case 0: /* look for leading 0b, 0o or 0x */
+ if (*str == '0') {
+ ++str;
+ if (*str == 'x' || *str == 'X') {
+ /* there must be at least one digit after 0x */
+ if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 16) {
+ if (ptr)
+ *ptr = (char *)str;
+ return 0;
+ }
+ ++str;
+ base = 16;
+ } else if (*str == 'o' || *str == 'O') {
+ /* there must be at least one digit after 0o */
+ if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 8) {
+ if (ptr)
+ *ptr = (char *)str;
+ return 0;
+ }
+ ++str;
+ base = 8;
+ } else if (*str == 'b' || *str == 'B') {
+ /* there must be at least one digit after 0b */
+ if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 2) {
+ if (ptr)
+ *ptr = (char *)str;
+ return 0;
+ }
+ ++str;
+ base = 2;
+ } else {
+ /* skip all zeroes... */
+ while (*str == '0')
+ ++str;
+ while (Py_ISSPACE(*str))
+ ++str;
+ if (ptr)
+ *ptr = (char *)str;
+ return 0;
+ }
+ }
+ else
+ base = 10;
+ break;
+
+ /* even with explicit base, skip leading 0? prefix */
+ case 16:
+ if (*str == '0') {
+ ++str;
+ if (*str == 'x' || *str == 'X') {
+ /* there must be at least one digit after 0x */
+ if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 16) {
+ if (ptr)
+ *ptr = (char *)str;
+ return 0;
+ }
+ ++str;
+ }
+ }
+ break;
+ case 8:
+ if (*str == '0') {
+ ++str;
+ if (*str == 'o' || *str == 'O') {
+ /* there must be at least one digit after 0o */
+ if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 8) {
+ if (ptr)
+ *ptr = (char *)str;
+ return 0;
+ }
+ ++str;
+ }
+ }
+ break;
+ case 2:
+ if(*str == '0') {
+ ++str;
+ if (*str == 'b' || *str == 'B') {
+ /* there must be at least one digit after 0b */
+ if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 2) {
+ if (ptr)
+ *ptr = (char *)str;
+ return 0;
+ }
+ ++str;
+ }
+ }
+ break;
+ }
+
+ /* catch silly bases */
+ if (base < 2 || base > 36) {
+ if (ptr)
+ *ptr = (char *)str;
+ return 0;
+ }
+
+ /* skip leading zeroes */
+ while (*str == '0')
+ ++str;
+
+ /* base is guaranteed to be in [2, 36] at this point */
+ ovlimit = digitlimit[base];
+
+ /* do the conversion until non-digit character encountered */
+ while ((c = _PyLong_DigitValue[Py_CHARMASK(*str)]) < base) {
+ if (ovlimit > 0) /* no overflow check required */
+ result = result * base + c;
+ else { /* requires overflow check */
+ unsigned long temp_result;
+
+ if (ovlimit < 0) /* guaranteed overflow */
+ goto overflowed;
+
+ /* there could be an overflow */
+ /* check overflow just from shifting */
+ if (result > smallmax[base])
+ goto overflowed;
+
+ result *= base;
+
+ /* check overflow from the digit's value */
+ temp_result = result + c;
+ if (temp_result < result)
+ goto overflowed;
+
+ result = temp_result;
+ }
+
+ ++str;
+ --ovlimit;
+ }
+
+ /* set pointer to point to the last character scanned */
+ if (ptr)
+ *ptr = (char *)str;
+
+ return result;
+
+overflowed:
+ if (ptr) {
+ /* spool through remaining digit characters */
+ while (_PyLong_DigitValue[Py_CHARMASK(*str)] < base)
+ ++str;
+ *ptr = (char *)str;
+ }
+ errno = ERANGE;
+ return (unsigned long)-1;
+}
+
+/* Checking for overflow in PyOS_strtol is a PITA; see comments
+ * about PY_ABS_LONG_MIN in longobject.c.
+ */
+#define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN)
+
+long
+PyOS_strtol(const char *str, char **ptr, int base)
+{
+ long result;
+ unsigned long uresult;
+ char sign;
+
+ while (*str && Py_ISSPACE(*str))
+ str++;
+
+ sign = *str;
+ if (sign == '+' || sign == '-')
+ str++;
+
+ uresult = PyOS_strtoul(str, ptr, base);
+
+ if (uresult <= (unsigned long)LONG_MAX) {
+ result = (long)uresult;
+ if (sign == '-')
+ result = -result;
+ }
+ else if (sign == '-' && uresult == PY_ABS_LONG_MIN) {
+ result = LONG_MIN;
+ }
+ else {
+ errno = ERANGE;
+ result = LONG_MAX;
+ }
+ return result;
+}
diff --git a/contrib/tools/python3/src/Python/opcode_targets.h b/contrib/tools/python3/src/Python/opcode_targets.h
new file mode 100644
index 00000000000..538fdbe3e0b
--- /dev/null
+++ b/contrib/tools/python3/src/Python/opcode_targets.h
@@ -0,0 +1,258 @@
+static void *opcode_targets[256] = {
+ &&_unknown_opcode,
+ &&TARGET_POP_TOP,
+ &&TARGET_ROT_TWO,
+ &&TARGET_ROT_THREE,
+ &&TARGET_DUP_TOP,
+ &&TARGET_DUP_TOP_TWO,
+ &&TARGET_ROT_FOUR,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&TARGET_NOP,
+ &&TARGET_UNARY_POSITIVE,
+ &&TARGET_UNARY_NEGATIVE,
+ &&TARGET_UNARY_NOT,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&TARGET_UNARY_INVERT,
+ &&TARGET_BINARY_MATRIX_MULTIPLY,
+ &&TARGET_INPLACE_MATRIX_MULTIPLY,
+ &&_unknown_opcode,
+ &&TARGET_BINARY_POWER,
+ &&TARGET_BINARY_MULTIPLY,
+ &&_unknown_opcode,
+ &&TARGET_BINARY_MODULO,
+ &&TARGET_BINARY_ADD,
+ &&TARGET_BINARY_SUBTRACT,
+ &&TARGET_BINARY_SUBSCR,
+ &&TARGET_BINARY_FLOOR_DIVIDE,
+ &&TARGET_BINARY_TRUE_DIVIDE,
+ &&TARGET_INPLACE_FLOOR_DIVIDE,
+ &&TARGET_INPLACE_TRUE_DIVIDE,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&TARGET_RERAISE,
+ &&TARGET_WITH_EXCEPT_START,
+ &&TARGET_GET_AITER,
+ &&TARGET_GET_ANEXT,
+ &&TARGET_BEFORE_ASYNC_WITH,
+ &&_unknown_opcode,
+ &&TARGET_END_ASYNC_FOR,
+ &&TARGET_INPLACE_ADD,
+ &&TARGET_INPLACE_SUBTRACT,
+ &&TARGET_INPLACE_MULTIPLY,
+ &&_unknown_opcode,
+ &&TARGET_INPLACE_MODULO,
+ &&TARGET_STORE_SUBSCR,
+ &&TARGET_DELETE_SUBSCR,
+ &&TARGET_BINARY_LSHIFT,
+ &&TARGET_BINARY_RSHIFT,
+ &&TARGET_BINARY_AND,
+ &&TARGET_BINARY_XOR,
+ &&TARGET_BINARY_OR,
+ &&TARGET_INPLACE_POWER,
+ &&TARGET_GET_ITER,
+ &&TARGET_GET_YIELD_FROM_ITER,
+ &&TARGET_PRINT_EXPR,
+ &&TARGET_LOAD_BUILD_CLASS,
+ &&TARGET_YIELD_FROM,
+ &&TARGET_GET_AWAITABLE,
+ &&TARGET_LOAD_ASSERTION_ERROR,
+ &&TARGET_INPLACE_LSHIFT,
+ &&TARGET_INPLACE_RSHIFT,
+ &&TARGET_INPLACE_AND,
+ &&TARGET_INPLACE_XOR,
+ &&TARGET_INPLACE_OR,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&TARGET_LIST_TO_TUPLE,
+ &&TARGET_RETURN_VALUE,
+ &&TARGET_IMPORT_STAR,
+ &&TARGET_SETUP_ANNOTATIONS,
+ &&TARGET_YIELD_VALUE,
+ &&TARGET_POP_BLOCK,
+ &&_unknown_opcode,
+ &&TARGET_POP_EXCEPT,
+ &&TARGET_STORE_NAME,
+ &&TARGET_DELETE_NAME,
+ &&TARGET_UNPACK_SEQUENCE,
+ &&TARGET_FOR_ITER,
+ &&TARGET_UNPACK_EX,
+ &&TARGET_STORE_ATTR,
+ &&TARGET_DELETE_ATTR,
+ &&TARGET_STORE_GLOBAL,
+ &&TARGET_DELETE_GLOBAL,
+ &&_unknown_opcode,
+ &&TARGET_LOAD_CONST,
+ &&TARGET_LOAD_NAME,
+ &&TARGET_BUILD_TUPLE,
+ &&TARGET_BUILD_LIST,
+ &&TARGET_BUILD_SET,
+ &&TARGET_BUILD_MAP,
+ &&TARGET_LOAD_ATTR,
+ &&TARGET_COMPARE_OP,
+ &&TARGET_IMPORT_NAME,
+ &&TARGET_IMPORT_FROM,
+ &&TARGET_JUMP_FORWARD,
+ &&TARGET_JUMP_IF_FALSE_OR_POP,
+ &&TARGET_JUMP_IF_TRUE_OR_POP,
+ &&TARGET_JUMP_ABSOLUTE,
+ &&TARGET_POP_JUMP_IF_FALSE,
+ &&TARGET_POP_JUMP_IF_TRUE,
+ &&TARGET_LOAD_GLOBAL,
+ &&TARGET_IS_OP,
+ &&TARGET_CONTAINS_OP,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&TARGET_JUMP_IF_NOT_EXC_MATCH,
+ &&TARGET_SETUP_FINALLY,
+ &&_unknown_opcode,
+ &&TARGET_LOAD_FAST,
+ &&TARGET_STORE_FAST,
+ &&TARGET_DELETE_FAST,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&TARGET_RAISE_VARARGS,
+ &&TARGET_CALL_FUNCTION,
+ &&TARGET_MAKE_FUNCTION,
+ &&TARGET_BUILD_SLICE,
+ &&_unknown_opcode,
+ &&TARGET_LOAD_CLOSURE,
+ &&TARGET_LOAD_DEREF,
+ &&TARGET_STORE_DEREF,
+ &&TARGET_DELETE_DEREF,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&TARGET_CALL_FUNCTION_KW,
+ &&TARGET_CALL_FUNCTION_EX,
+ &&TARGET_SETUP_WITH,
+ &&TARGET_EXTENDED_ARG,
+ &&TARGET_LIST_APPEND,
+ &&TARGET_SET_ADD,
+ &&TARGET_MAP_ADD,
+ &&TARGET_LOAD_CLASSDEREF,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&TARGET_SETUP_ASYNC_WITH,
+ &&TARGET_FORMAT_VALUE,
+ &&TARGET_BUILD_CONST_KEY_MAP,
+ &&TARGET_BUILD_STRING,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&TARGET_LOAD_METHOD,
+ &&TARGET_CALL_METHOD,
+ &&TARGET_LIST_EXTEND,
+ &&TARGET_SET_UPDATE,
+ &&TARGET_DICT_MERGE,
+ &&TARGET_DICT_UPDATE,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode,
+ &&_unknown_opcode
+};
diff --git a/contrib/tools/python3/src/Python/pathconfig.c b/contrib/tools/python3/src/Python/pathconfig.c
new file mode 100644
index 00000000000..b2ce86e64ce
--- /dev/null
+++ b/contrib/tools/python3/src/Python/pathconfig.c
@@ -0,0 +1,803 @@
+/* Path configuration like module_search_path (sys.path) */
+
+#include "Python.h"
+#include "osdefs.h" // DELIM
+#include "pycore_initconfig.h"
+#include "pycore_fileutils.h"
+#include "pycore_pathconfig.h"
+#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
+#include <wchar.h>
+#ifdef MS_WINDOWS
+# include <windows.h> // GetFullPathNameW(), MAX_PATH
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+_PyPathConfig _Py_path_config = _PyPathConfig_INIT;
+
+
+static int
+copy_wstr(wchar_t **dst, const wchar_t *src)
+{
+ assert(*dst == NULL);
+ if (src != NULL) {
+ *dst = _PyMem_RawWcsdup(src);
+ if (*dst == NULL) {
+ return -1;
+ }
+ }
+ else {
+ *dst = NULL;
+ }
+ return 0;
+}
+
+
+static void
+pathconfig_clear(_PyPathConfig *config)
+{
+ /* _PyMem_SetDefaultAllocator() is needed to get a known memory allocator,
+ since Py_SetPath(), Py_SetPythonHome() and Py_SetProgramName() can be
+ called before Py_Initialize() which can changes the memory allocator. */
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+#define CLEAR(ATTR) \
+ do { \
+ PyMem_RawFree(ATTR); \
+ ATTR = NULL; \
+ } while (0)
+
+ CLEAR(config->program_full_path);
+ CLEAR(config->prefix);
+ CLEAR(config->exec_prefix);
+ CLEAR(config->module_search_path);
+ CLEAR(config->program_name);
+ CLEAR(config->home);
+#ifdef MS_WINDOWS
+ CLEAR(config->base_executable);
+#endif
+
+#undef CLEAR
+
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+}
+
+
+static PyStatus
+pathconfig_copy(_PyPathConfig *config, const _PyPathConfig *config2)
+{
+ pathconfig_clear(config);
+
+#define COPY_ATTR(ATTR) \
+ do { \
+ if (copy_wstr(&config->ATTR, config2->ATTR) < 0) { \
+ return _PyStatus_NO_MEMORY(); \
+ } \
+ } while (0)
+
+ COPY_ATTR(program_full_path);
+ COPY_ATTR(prefix);
+ COPY_ATTR(exec_prefix);
+ COPY_ATTR(module_search_path);
+ COPY_ATTR(program_name);
+ COPY_ATTR(home);
+#ifdef MS_WINDOWS
+ config->isolated = config2->isolated;
+ config->site_import = config2->site_import;
+ COPY_ATTR(base_executable);
+#endif
+
+#undef COPY_ATTR
+
+ return _PyStatus_OK();
+}
+
+
+void
+_PyPathConfig_ClearGlobal(void)
+{
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ pathconfig_clear(&_Py_path_config);
+
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+}
+
+
+static wchar_t*
+_PyWideStringList_Join(const PyWideStringList *list, wchar_t sep)
+{
+ size_t len = 1; /* NUL terminator */
+ for (Py_ssize_t i=0; i < list->length; i++) {
+ if (i != 0) {
+ len++;
+ }
+ len += wcslen(list->items[i]);
+ }
+
+ wchar_t *text = PyMem_RawMalloc(len * sizeof(wchar_t));
+ if (text == NULL) {
+ return NULL;
+ }
+ wchar_t *str = text;
+ for (Py_ssize_t i=0; i < list->length; i++) {
+ wchar_t *path = list->items[i];
+ if (i != 0) {
+ *str++ = sep;
+ }
+ len = wcslen(path);
+ memcpy(str, path, len * sizeof(wchar_t));
+ str += len;
+ }
+ *str = L'\0';
+
+ return text;
+}
+
+
+static PyStatus
+pathconfig_set_from_config(_PyPathConfig *pathconfig, const PyConfig *config)
+{
+ PyStatus status;
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ if (config->module_search_paths_set) {
+ PyMem_RawFree(pathconfig->module_search_path);
+ pathconfig->module_search_path = _PyWideStringList_Join(&config->module_search_paths, DELIM);
+ if (pathconfig->module_search_path == NULL) {
+ goto no_memory;
+ }
+ }
+
+#define COPY_CONFIG(PATH_ATTR, CONFIG_ATTR) \
+ if (config->CONFIG_ATTR) { \
+ PyMem_RawFree(pathconfig->PATH_ATTR); \
+ pathconfig->PATH_ATTR = NULL; \
+ if (copy_wstr(&pathconfig->PATH_ATTR, config->CONFIG_ATTR) < 0) { \
+ goto no_memory; \
+ } \
+ }
+
+ COPY_CONFIG(program_full_path, executable);
+ COPY_CONFIG(prefix, prefix);
+ COPY_CONFIG(exec_prefix, exec_prefix);
+ COPY_CONFIG(program_name, program_name);
+ COPY_CONFIG(home, home);
+#ifdef MS_WINDOWS
+ COPY_CONFIG(base_executable, base_executable);
+#endif
+
+#undef COPY_CONFIG
+
+ status = _PyStatus_OK();
+ goto done;
+
+no_memory:
+ status = _PyStatus_NO_MEMORY();
+
+done:
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+ return status;
+}
+
+
+PyStatus
+_PyConfig_WritePathConfig(const PyConfig *config)
+{
+ return pathconfig_set_from_config(&_Py_path_config, config);
+}
+
+
+static PyStatus
+config_init_module_search_paths(PyConfig *config, _PyPathConfig *pathconfig)
+{
+ assert(!config->module_search_paths_set);
+
+ _PyWideStringList_Clear(&config->module_search_paths);
+
+ const wchar_t *sys_path = pathconfig->module_search_path;
+ const wchar_t delim = DELIM;
+ while (1) {
+ const wchar_t *p = wcschr(sys_path, delim);
+ if (p == NULL) {
+ p = sys_path + wcslen(sys_path); /* End of string */
+ }
+
+ size_t path_len = (p - sys_path);
+ wchar_t *path = PyMem_RawMalloc((path_len + 1) * sizeof(wchar_t));
+ if (path == NULL) {
+ return _PyStatus_NO_MEMORY();
+ }
+ memcpy(path, sys_path, path_len * sizeof(wchar_t));
+ path[path_len] = L'\0';
+
+ PyStatus status = PyWideStringList_Append(&config->module_search_paths, path);
+ PyMem_RawFree(path);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ if (*p == '\0') {
+ break;
+ }
+ sys_path = p + 1;
+ }
+ config->module_search_paths_set = 1;
+ return _PyStatus_OK();
+}
+
+
+/* Calculate the path configuration:
+
+ - exec_prefix
+ - module_search_path
+ - prefix
+ - program_full_path
+
+ On Windows, more fields are calculated:
+
+ - base_executable
+ - isolated
+ - site_import
+
+ On other platforms, isolated and site_import are left unchanged, and
+ _PyConfig_InitPathConfig() copies executable to base_executable (if it's not
+ set).
+
+ Priority, highest to lowest:
+
+ - PyConfig
+ - _Py_path_config: set by Py_SetPath(), Py_SetPythonHome()
+ and Py_SetProgramName()
+ - _PyPathConfig_Calculate()
+*/
+static PyStatus
+pathconfig_calculate(_PyPathConfig *pathconfig, const PyConfig *config)
+{
+ PyStatus status;
+
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ status = pathconfig_copy(pathconfig, &_Py_path_config);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+
+ status = pathconfig_set_from_config(pathconfig, config);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+
+ if (_Py_path_config.module_search_path == NULL) {
+ status = _PyPathConfig_Calculate(pathconfig, config);
+ }
+ else {
+ /* Py_SetPath() has been called: avoid _PyPathConfig_Calculate() */
+ }
+
+done:
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+ return status;
+}
+
+
+static PyStatus
+config_calculate_pathconfig(PyConfig *config)
+{
+ _PyPathConfig pathconfig = _PyPathConfig_INIT;
+ PyStatus status;
+
+ status = pathconfig_calculate(&pathconfig, config);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+
+ if (!config->module_search_paths_set) {
+ status = config_init_module_search_paths(config, &pathconfig);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+ }
+
+#define COPY_ATTR(PATH_ATTR, CONFIG_ATTR) \
+ if (config->CONFIG_ATTR == NULL) { \
+ if (copy_wstr(&config->CONFIG_ATTR, pathconfig.PATH_ATTR) < 0) { \
+ goto no_memory; \
+ } \
+ }
+
+#ifdef MS_WINDOWS
+ if (config->executable != NULL && config->base_executable == NULL) {
+ /* If executable is set explicitly in the configuration,
+ ignore calculated base_executable: _PyConfig_InitPathConfig()
+ will copy executable to base_executable */
+ }
+ else {
+ COPY_ATTR(base_executable, base_executable);
+ }
+#endif
+
+ COPY_ATTR(program_full_path, executable);
+ COPY_ATTR(prefix, prefix);
+ COPY_ATTR(exec_prefix, exec_prefix);
+
+#undef COPY_ATTR
+
+#ifdef MS_WINDOWS
+ /* If a ._pth file is found: isolated and site_import are overridden */
+ if (pathconfig.isolated != -1) {
+ config->isolated = pathconfig.isolated;
+ }
+ if (pathconfig.site_import != -1) {
+ config->site_import = pathconfig.site_import;
+ }
+#endif
+
+ status = _PyStatus_OK();
+ goto done;
+
+no_memory:
+ status = _PyStatus_NO_MEMORY();
+
+done:
+ pathconfig_clear(&pathconfig);
+ return status;
+}
+
+
+PyStatus
+_PyConfig_InitPathConfig(PyConfig *config)
+{
+ /* Do we need to calculate the path? */
+ if (!config->module_search_paths_set
+ || config->executable == NULL
+ || config->prefix == NULL
+ || config->exec_prefix == NULL)
+ {
+ PyStatus status = config_calculate_pathconfig(config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ if (config->base_prefix == NULL) {
+ if (copy_wstr(&config->base_prefix, config->prefix) < 0) {
+ return _PyStatus_NO_MEMORY();
+ }
+ }
+
+ if (config->base_exec_prefix == NULL) {
+ if (copy_wstr(&config->base_exec_prefix,
+ config->exec_prefix) < 0) {
+ return _PyStatus_NO_MEMORY();
+ }
+ }
+
+ if (config->base_executable == NULL) {
+ if (copy_wstr(&config->base_executable,
+ config->executable) < 0) {
+ return _PyStatus_NO_MEMORY();
+ }
+ }
+
+ return _PyStatus_OK();
+}
+
+
+static PyStatus
+pathconfig_global_read(_PyPathConfig *pathconfig)
+{
+ PyConfig config;
+ _PyConfig_InitCompatConfig(&config);
+
+ /* Call _PyConfig_InitPathConfig() */
+ PyStatus status = PyConfig_Read(&config);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+
+ status = pathconfig_set_from_config(pathconfig, &config);
+
+done:
+ PyConfig_Clear(&config);
+ return status;
+}
+
+
+static void
+pathconfig_global_init(void)
+{
+ PyStatus status;
+
+ if (_Py_path_config.module_search_path == NULL) {
+ status = pathconfig_global_read(&_Py_path_config);
+ if (_PyStatus_EXCEPTION(status)) {
+ Py_ExitStatusException(status);
+ }
+ }
+ else {
+ /* Global configuration already initialized */
+ }
+
+ assert(_Py_path_config.program_full_path != NULL);
+ assert(_Py_path_config.prefix != NULL);
+ assert(_Py_path_config.exec_prefix != NULL);
+ assert(_Py_path_config.module_search_path != NULL);
+ assert(_Py_path_config.program_name != NULL);
+ /* home can be NULL */
+#ifdef MS_WINDOWS
+ assert(_Py_path_config.base_executable != NULL);
+#endif
+}
+
+
+/* External interface */
+
+static void _Py_NO_RETURN
+path_out_of_memory(const char *func)
+{
+ _Py_FatalErrorFunc(func, "out of memory");
+}
+
+void
+Py_SetPath(const wchar_t *path)
+{
+ if (path == NULL) {
+ pathconfig_clear(&_Py_path_config);
+ return;
+ }
+
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ /* Getting the program full path calls pathconfig_global_init() */
+ wchar_t *program_full_path = _PyMem_RawWcsdup(Py_GetProgramFullPath());
+
+ PyMem_RawFree(_Py_path_config.program_full_path);
+ PyMem_RawFree(_Py_path_config.prefix);
+ PyMem_RawFree(_Py_path_config.exec_prefix);
+ PyMem_RawFree(_Py_path_config.module_search_path);
+
+ _Py_path_config.program_full_path = program_full_path;
+ _Py_path_config.prefix = _PyMem_RawWcsdup(L"");
+ _Py_path_config.exec_prefix = _PyMem_RawWcsdup(L"");
+ _Py_path_config.module_search_path = _PyMem_RawWcsdup(path);
+
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ if (_Py_path_config.program_full_path == NULL
+ || _Py_path_config.prefix == NULL
+ || _Py_path_config.exec_prefix == NULL
+ || _Py_path_config.module_search_path == NULL)
+ {
+ path_out_of_memory(__func__);
+ }
+}
+
+
+void
+Py_SetPythonHome(const wchar_t *home)
+{
+ if (home == NULL) {
+ return;
+ }
+
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ PyMem_RawFree(_Py_path_config.home);
+ _Py_path_config.home = _PyMem_RawWcsdup(home);
+
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ if (_Py_path_config.home == NULL) {
+ path_out_of_memory(__func__);
+ }
+}
+
+
+void
+Py_SetProgramName(const wchar_t *program_name)
+{
+ if (program_name == NULL || program_name[0] == L'\0') {
+ return;
+ }
+
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ PyMem_RawFree(_Py_path_config.program_name);
+ _Py_path_config.program_name = _PyMem_RawWcsdup(program_name);
+
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ if (_Py_path_config.program_name == NULL) {
+ path_out_of_memory(__func__);
+ }
+}
+
+void
+_Py_SetProgramFullPath(const wchar_t *program_full_path)
+{
+ if (program_full_path == NULL || program_full_path[0] == L'\0') {
+ return;
+ }
+
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ PyMem_RawFree(_Py_path_config.program_full_path);
+ _Py_path_config.program_full_path = _PyMem_RawWcsdup(program_full_path);
+
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ if (_Py_path_config.program_full_path == NULL) {
+ path_out_of_memory(__func__);
+ }
+}
+
+
+wchar_t *
+Py_GetPath(void)
+{
+ pathconfig_global_init();
+ return _Py_path_config.module_search_path;
+}
+
+
+wchar_t *
+Py_GetPrefix(void)
+{
+ pathconfig_global_init();
+ return _Py_path_config.prefix;
+}
+
+
+wchar_t *
+Py_GetExecPrefix(void)
+{
+ pathconfig_global_init();
+ return _Py_path_config.exec_prefix;
+}
+
+
+wchar_t *
+Py_GetProgramFullPath(void)
+{
+ pathconfig_global_init();
+ return _Py_path_config.program_full_path;
+}
+
+
+wchar_t*
+Py_GetPythonHome(void)
+{
+ pathconfig_global_init();
+ return _Py_path_config.home;
+}
+
+
+wchar_t *
+Py_GetProgramName(void)
+{
+ pathconfig_global_init();
+ return _Py_path_config.program_name;
+}
+
+/* Compute module search path from argv[0] or the current working
+ directory ("-m module" case) which will be prepended to sys.argv:
+ sys.path[0].
+
+ Return 1 if the path is correctly resolved and written into *path0_p.
+
+ Return 0 if it fails to resolve the full path. For example, return 0 if the
+ current working directory has been removed (bpo-36236) or if argv is empty.
+
+ Raise an exception and return -1 on error.
+ */
+int
+_PyPathConfig_ComputeSysPath0(const PyWideStringList *argv, PyObject **path0_p)
+{
+ assert(_PyWideStringList_CheckConsistency(argv));
+
+ if (argv->length == 0) {
+ /* Leave sys.path unchanged if sys.argv is empty */
+ return 0;
+ }
+
+ wchar_t *argv0 = argv->items[0];
+ int have_module_arg = (wcscmp(argv0, L"-m") == 0);
+ int have_script_arg = (!have_module_arg && (wcscmp(argv0, L"-c") != 0));
+
+ wchar_t *path0 = argv0;
+ Py_ssize_t n = 0;
+
+#ifdef HAVE_REALPATH
+ wchar_t fullpath[MAXPATHLEN];
+#elif defined(MS_WINDOWS)
+ wchar_t fullpath[MAX_PATH];
+#endif
+
+ if (have_module_arg) {
+#if defined(HAVE_REALPATH) || defined(MS_WINDOWS)
+ if (!_Py_wgetcwd(fullpath, Py_ARRAY_LENGTH(fullpath))) {
+ return 0;
+ }
+ path0 = fullpath;
+#else
+ path0 = L".";
+#endif
+ n = wcslen(path0);
+ }
+
+#ifdef HAVE_READLINK
+ wchar_t link[MAXPATHLEN + 1];
+ int nr = 0;
+ wchar_t path0copy[2 * MAXPATHLEN + 1];
+
+ if (have_script_arg) {
+ nr = _Py_wreadlink(path0, link, Py_ARRAY_LENGTH(link));
+ }
+ if (nr > 0) {
+ /* It's a symlink */
+ link[nr] = '\0';
+ if (link[0] == SEP) {
+ path0 = link; /* Link to absolute path */
+ }
+ else if (wcschr(link, SEP) == NULL) {
+ /* Link without path */
+ }
+ else {
+ /* Must join(dirname(path0), link) */
+ wchar_t *q = wcsrchr(path0, SEP);
+ if (q == NULL) {
+ /* path0 without path */
+ path0 = link;
+ }
+ else {
+ /* Must make a copy, path0copy has room for 2 * MAXPATHLEN */
+ wcsncpy(path0copy, path0, MAXPATHLEN);
+ q = wcsrchr(path0copy, SEP);
+ wcsncpy(q+1, link, MAXPATHLEN);
+ q[MAXPATHLEN + 1] = L'\0';
+ path0 = path0copy;
+ }
+ }
+ }
+#endif /* HAVE_READLINK */
+
+ wchar_t *p = NULL;
+
+#if SEP == '\\'
+ /* Special case for Microsoft filename syntax */
+ if (have_script_arg) {
+ wchar_t *q;
+#if defined(MS_WINDOWS)
+ /* Replace the first element in argv with the full path. */
+ wchar_t *ptemp;
+ if (GetFullPathNameW(path0,
+ Py_ARRAY_LENGTH(fullpath),
+ fullpath,
+ &ptemp)) {
+ path0 = fullpath;
+ }
+#endif
+ p = wcsrchr(path0, SEP);
+ /* Test for alternate separator */
+ q = wcsrchr(p ? p : path0, '/');
+ if (q != NULL)
+ p = q;
+ if (p != NULL) {
+ n = p + 1 - path0;
+ if (n > 1 && p[-1] != ':')
+ n--; /* Drop trailing separator */
+ }
+ }
+#else
+ /* All other filename syntaxes */
+ if (have_script_arg) {
+#if defined(HAVE_REALPATH)
+ if (_Py_wrealpath(path0, fullpath, Py_ARRAY_LENGTH(fullpath))) {
+ path0 = fullpath;
+ }
+#endif
+ p = wcsrchr(path0, SEP);
+ }
+ if (p != NULL) {
+ n = p + 1 - path0;
+#if SEP == '/' /* Special case for Unix filename syntax */
+ if (n > 1) {
+ /* Drop trailing separator */
+ n--;
+ }
+#endif /* Unix */
+ }
+#endif /* All others */
+
+ PyObject *path0_obj = PyUnicode_FromWideChar(path0, n);
+ if (path0_obj == NULL) {
+ return -1;
+ }
+
+ *path0_p = path0_obj;
+ return 1;
+}
+
+
+#ifdef MS_WINDOWS
+#define WCSTOK wcstok_s
+#else
+#define WCSTOK wcstok
+#endif
+
+/* Search for a prefix value in an environment file (pyvenv.cfg).
+
+ - If found, copy it into *value_p: string which must be freed by
+ PyMem_RawFree().
+ - If not found, *value_p is set to NULL.
+*/
+PyStatus
+_Py_FindEnvConfigValue(FILE *env_file, const wchar_t *key,
+ wchar_t **value_p)
+{
+ *value_p = NULL;
+
+ char buffer[MAXPATHLEN * 2 + 1]; /* allow extra for key, '=', etc. */
+ buffer[Py_ARRAY_LENGTH(buffer)-1] = '\0';
+
+ while (!feof(env_file)) {
+ char * p = fgets(buffer, Py_ARRAY_LENGTH(buffer) - 1, env_file);
+
+ if (p == NULL) {
+ break;
+ }
+
+ size_t n = strlen(p);
+ if (p[n - 1] != '\n') {
+ /* line has overflowed - bail */
+ break;
+ }
+ if (p[0] == '#') {
+ /* Comment - skip */
+ continue;
+ }
+
+ wchar_t *tmpbuffer = _Py_DecodeUTF8_surrogateescape(buffer, n, NULL);
+ if (tmpbuffer) {
+ wchar_t * state;
+ wchar_t * tok = WCSTOK(tmpbuffer, L" \t\r\n", &state);
+ if ((tok != NULL) && !wcscmp(tok, key)) {
+ tok = WCSTOK(NULL, L" \t", &state);
+ if ((tok != NULL) && !wcscmp(tok, L"=")) {
+ tok = WCSTOK(NULL, L"\r\n", &state);
+ if (tok != NULL) {
+ *value_p = _PyMem_RawWcsdup(tok);
+ PyMem_RawFree(tmpbuffer);
+
+ if (*value_p == NULL) {
+ return _PyStatus_NO_MEMORY();
+ }
+
+ /* found */
+ return _PyStatus_OK();
+ }
+ }
+ }
+ PyMem_RawFree(tmpbuffer);
+ }
+ }
+
+ /* not found */
+ return _PyStatus_OK();
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/contrib/tools/python3/src/Python/peephole.c b/contrib/tools/python3/src/Python/peephole.c
new file mode 100644
index 00000000000..6954c87b13b
--- /dev/null
+++ b/contrib/tools/python3/src/Python/peephole.c
@@ -0,0 +1,538 @@
+/* Peephole optimizations for bytecode compiler. */
+
+#include "Python.h"
+
+#include "Python-ast.h"
+#include "node.h"
+#include "ast.h"
+#include "code.h"
+#include "symtable.h"
+#include "opcode.h"
+#include "wordcode_helpers.h"
+
+#define UNCONDITIONAL_JUMP(op) (op==JUMP_ABSOLUTE || op==JUMP_FORWARD)
+#define CONDITIONAL_JUMP(op) (op==POP_JUMP_IF_FALSE || op==POP_JUMP_IF_TRUE \
+ || op==JUMP_IF_FALSE_OR_POP || op==JUMP_IF_TRUE_OR_POP)
+#define ABSOLUTE_JUMP(op) (op==JUMP_ABSOLUTE \
+ || op==POP_JUMP_IF_FALSE || op==POP_JUMP_IF_TRUE \
+ || op==JUMP_IF_FALSE_OR_POP || op==JUMP_IF_TRUE_OR_POP || op==JUMP_IF_NOT_EXC_MATCH)
+#define JUMPS_ON_TRUE(op) (op==POP_JUMP_IF_TRUE || op==JUMP_IF_TRUE_OR_POP)
+#define GETJUMPTGT(arr, i) (get_arg(arr, i) / sizeof(_Py_CODEUNIT) + \
+ (ABSOLUTE_JUMP(_Py_OPCODE(arr[i])) ? 0 : i+1))
+#define ISBASICBLOCK(blocks, start, end) \
+ (blocks[start]==blocks[end])
+
+
+/* Scans back N consecutive LOAD_CONST instructions, skipping NOPs,
+ returns index of the Nth last's LOAD_CONST's EXTENDED_ARG prefix.
+ Callers are responsible to check CONST_STACK_LEN beforehand.
+*/
+static Py_ssize_t
+lastn_const_start(const _Py_CODEUNIT *codestr, Py_ssize_t i, Py_ssize_t n)
+{
+ assert(n > 0);
+ for (;;) {
+ i--;
+ assert(i >= 0);
+ if (_Py_OPCODE(codestr[i]) == LOAD_CONST) {
+ if (!--n) {
+ while (i > 0 && _Py_OPCODE(codestr[i-1]) == EXTENDED_ARG) {
+ i--;
+ }
+ return i;
+ }
+ }
+ else {
+ assert(_Py_OPCODE(codestr[i]) == EXTENDED_ARG);
+ }
+ }
+}
+
+/* Scans through EXTENDED ARGs, seeking the index of the effective opcode */
+static Py_ssize_t
+find_op(const _Py_CODEUNIT *codestr, Py_ssize_t codelen, Py_ssize_t i)
+{
+ while (i < codelen && _Py_OPCODE(codestr[i]) == EXTENDED_ARG) {
+ i++;
+ }
+ return i;
+}
+
+/* Given the index of the effective opcode,
+ scan back to construct the oparg with EXTENDED_ARG */
+static unsigned int
+get_arg(const _Py_CODEUNIT *codestr, Py_ssize_t i)
+{
+ _Py_CODEUNIT word;
+ unsigned int oparg = _Py_OPARG(codestr[i]);
+ if (i >= 1 && _Py_OPCODE(word = codestr[i-1]) == EXTENDED_ARG) {
+ oparg |= _Py_OPARG(word) << 8;
+ if (i >= 2 && _Py_OPCODE(word = codestr[i-2]) == EXTENDED_ARG) {
+ oparg |= _Py_OPARG(word) << 16;
+ if (i >= 3 && _Py_OPCODE(word = codestr[i-3]) == EXTENDED_ARG) {
+ oparg |= _Py_OPARG(word) << 24;
+ }
+ }
+ }
+ return oparg;
+}
+
+/* Fill the region with NOPs. */
+static void
+fill_nops(_Py_CODEUNIT *codestr, Py_ssize_t start, Py_ssize_t end)
+{
+ memset(codestr + start, NOP, (end - start) * sizeof(_Py_CODEUNIT));
+}
+
+/* Given the index of the effective opcode,
+ attempt to replace the argument, taking into account EXTENDED_ARG.
+ Returns -1 on failure, or the new op index on success */
+static Py_ssize_t
+set_arg(_Py_CODEUNIT *codestr, Py_ssize_t i, unsigned int oparg)
+{
+ unsigned int curarg = get_arg(codestr, i);
+ int curilen, newilen;
+ if (curarg == oparg)
+ return i;
+ curilen = instrsize(curarg);
+ newilen = instrsize(oparg);
+ if (curilen < newilen) {
+ return -1;
+ }
+
+ write_op_arg(codestr + i + 1 - curilen, _Py_OPCODE(codestr[i]), oparg, newilen);
+ fill_nops(codestr, i + 1 - curilen + newilen, i + 1);
+ return i-curilen+newilen;
+}
+
+/* Attempt to write op/arg at end of specified region of memory.
+ Preceding memory in the region is overwritten with NOPs.
+ Returns -1 on failure, op index on success */
+static Py_ssize_t
+copy_op_arg(_Py_CODEUNIT *codestr, Py_ssize_t i, unsigned char op,
+ unsigned int oparg, Py_ssize_t maxi)
+{
+ int ilen = instrsize(oparg);
+ if (i + ilen > maxi) {
+ return -1;
+ }
+ write_op_arg(codestr + maxi - ilen, op, oparg, ilen);
+ fill_nops(codestr, i, maxi - ilen);
+ return maxi - 1;
+}
+
+/* Replace LOAD_CONST c1, LOAD_CONST c2 ... LOAD_CONST cn, BUILD_TUPLE n
+ with LOAD_CONST (c1, c2, ... cn).
+ The consts table must still be in list form so that the
+ new constant (c1, c2, ... cn) can be appended.
+ Called with codestr pointing to the first LOAD_CONST.
+*/
+static Py_ssize_t
+fold_tuple_on_constants(_Py_CODEUNIT *codestr, Py_ssize_t codelen,
+ Py_ssize_t c_start, Py_ssize_t opcode_end,
+ PyObject *consts, int n)
+{
+ /* Pre-conditions */
+ assert(PyList_CheckExact(consts));
+
+ /* Buildup new tuple of constants */
+ PyObject *newconst = PyTuple_New(n);
+ if (newconst == NULL) {
+ return -1;
+ }
+
+ for (Py_ssize_t i = 0, pos = c_start; i < n; i++, pos++) {
+ assert(pos < opcode_end);
+ pos = find_op(codestr, codelen, pos);
+ assert(_Py_OPCODE(codestr[pos]) == LOAD_CONST);
+
+ unsigned int arg = get_arg(codestr, pos);
+ PyObject *constant = PyList_GET_ITEM(consts, arg);
+ Py_INCREF(constant);
+ PyTuple_SET_ITEM(newconst, i, constant);
+ }
+
+ Py_ssize_t index = PyList_GET_SIZE(consts);
+#if SIZEOF_SIZE_T > SIZEOF_INT
+ if ((size_t)index >= UINT_MAX - 1) {
+ Py_DECREF(newconst);
+ PyErr_SetString(PyExc_OverflowError, "too many constants");
+ return -1;
+ }
+#endif
+
+ /* Append folded constant onto consts */
+ if (PyList_Append(consts, newconst)) {
+ Py_DECREF(newconst);
+ return -1;
+ }
+ Py_DECREF(newconst);
+
+ return copy_op_arg(codestr, c_start, LOAD_CONST,
+ (unsigned int)index, opcode_end);
+}
+
+static unsigned int *
+markblocks(_Py_CODEUNIT *code, Py_ssize_t len)
+{
+ unsigned int *blocks = PyMem_New(unsigned int, len);
+ int i, j, opcode, blockcnt = 0;
+
+ if (blocks == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ memset(blocks, 0, len*sizeof(int));
+
+ /* Mark labels in the first pass */
+ for (i = 0; i < len; i++) {
+ opcode = _Py_OPCODE(code[i]);
+ switch (opcode) {
+ case FOR_ITER:
+ case JUMP_FORWARD:
+ case JUMP_IF_FALSE_OR_POP:
+ case JUMP_IF_TRUE_OR_POP:
+ case POP_JUMP_IF_FALSE:
+ case POP_JUMP_IF_TRUE:
+ case JUMP_IF_NOT_EXC_MATCH:
+ case JUMP_ABSOLUTE:
+ case SETUP_FINALLY:
+ case SETUP_WITH:
+ case SETUP_ASYNC_WITH:
+ j = GETJUMPTGT(code, i);
+ assert(j < len);
+ blocks[j] = 1;
+ break;
+ }
+ }
+ /* Build block numbers in the second pass */
+ for (i = 0; i < len; i++) {
+ blockcnt += blocks[i]; /* increment blockcnt over labels */
+ blocks[i] = blockcnt;
+ }
+ return blocks;
+}
+
+/* Perform basic peephole optimizations to components of a code object.
+ The consts object should still be in list form to allow new constants
+ to be appended.
+
+ To keep the optimizer simple, it bails when the lineno table has complex
+ encoding for gaps >= 255.
+
+ Optimizations are restricted to simple transformations occurring within a
+ single basic block. All transformations keep the code size the same or
+ smaller. For those that reduce size, the gaps are initially filled with
+ NOPs. Later those NOPs are removed and the jump addresses retargeted in
+ a single pass. */
+
+PyObject *
+PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
+ PyObject *lnotab_obj)
+{
+ Py_ssize_t h, i, nexti, op_start, tgt;
+ unsigned int j, nops;
+ unsigned char opcode, nextop;
+ _Py_CODEUNIT *codestr = NULL;
+ unsigned char *lnotab;
+ unsigned int cum_orig_offset, last_offset;
+ Py_ssize_t tabsiz;
+ // Count runs of consecutive LOAD_CONSTs
+ unsigned int cumlc = 0, lastlc = 0;
+ unsigned int *blocks = NULL;
+
+ /* Bail out if an exception is set */
+ if (PyErr_Occurred())
+ goto exitError;
+
+ /* Bypass optimization when the lnotab table is too complex */
+ assert(PyBytes_Check(lnotab_obj));
+ lnotab = (unsigned char*)PyBytes_AS_STRING(lnotab_obj);
+ tabsiz = PyBytes_GET_SIZE(lnotab_obj);
+ assert(tabsiz == 0 || Py_REFCNT(lnotab_obj) == 1);
+
+ /* Don't optimize if lnotab contains instruction pointer delta larger
+ than +255 (encoded as multiple bytes), just to keep the peephole optimizer
+ simple. The optimizer leaves line number deltas unchanged. */
+
+ for (i = 0; i < tabsiz; i += 2) {
+ if (lnotab[i] == 255) {
+ goto exitUnchanged;
+ }
+ }
+
+ assert(PyBytes_Check(code));
+ Py_ssize_t codesize = PyBytes_GET_SIZE(code);
+ assert(codesize % sizeof(_Py_CODEUNIT) == 0);
+ Py_ssize_t codelen = codesize / sizeof(_Py_CODEUNIT);
+ if (codelen > INT_MAX) {
+ /* Python assembler is limited to INT_MAX: see assembler.a_offset in
+ compile.c. */
+ goto exitUnchanged;
+ }
+
+ /* Make a modifiable copy of the code string */
+ codestr = (_Py_CODEUNIT *)PyMem_Malloc(codesize);
+ if (codestr == NULL) {
+ PyErr_NoMemory();
+ goto exitError;
+ }
+ memcpy(codestr, PyBytes_AS_STRING(code), codesize);
+
+ blocks = markblocks(codestr, codelen);
+ if (blocks == NULL)
+ goto exitError;
+ assert(PyList_Check(consts));
+
+ for (i=find_op(codestr, codelen, 0) ; i<codelen ; i=nexti) {
+ opcode = _Py_OPCODE(codestr[i]);
+ op_start = i;
+ while (op_start >= 1 && _Py_OPCODE(codestr[op_start-1]) == EXTENDED_ARG) {
+ op_start--;
+ }
+
+ nexti = i + 1;
+ while (nexti < codelen && _Py_OPCODE(codestr[nexti]) == EXTENDED_ARG)
+ nexti++;
+ nextop = nexti < codelen ? _Py_OPCODE(codestr[nexti]) : 0;
+
+ lastlc = cumlc;
+ cumlc = 0;
+
+ switch (opcode) {
+ /* Skip over LOAD_CONST trueconst
+ POP_JUMP_IF_FALSE xx. This improves
+ "while 1" performance. */
+ case LOAD_CONST:
+ cumlc = lastlc + 1;
+ if (nextop != POP_JUMP_IF_FALSE ||
+ !ISBASICBLOCK(blocks, op_start, i + 1)) {
+ break;
+ }
+ PyObject* cnt = PyList_GET_ITEM(consts, get_arg(codestr, i));
+ int is_true = PyObject_IsTrue(cnt);
+ if (is_true == -1) {
+ goto exitError;
+ }
+ if (is_true == 1) {
+ fill_nops(codestr, op_start, nexti + 1);
+ cumlc = 0;
+ }
+ break;
+
+ /* Try to fold tuples of constants.
+ Skip over BUILD_SEQN 1 UNPACK_SEQN 1.
+ Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2.
+ Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */
+ case BUILD_TUPLE:
+ j = get_arg(codestr, i);
+ if (j > 0 && lastlc >= j) {
+ h = lastn_const_start(codestr, op_start, j);
+ if (ISBASICBLOCK(blocks, h, op_start)) {
+ h = fold_tuple_on_constants(codestr, codelen,
+ h, i+1, consts, j);
+ break;
+ }
+ }
+ if (nextop != UNPACK_SEQUENCE ||
+ !ISBASICBLOCK(blocks, op_start, i + 1) ||
+ j != get_arg(codestr, nexti))
+ break;
+ if (j < 2) {
+ fill_nops(codestr, op_start, nexti + 1);
+ } else if (j == 2) {
+ codestr[op_start] = PACKOPARG(ROT_TWO, 0);
+ fill_nops(codestr, op_start + 1, nexti + 1);
+ } else if (j == 3) {
+ codestr[op_start] = PACKOPARG(ROT_THREE, 0);
+ codestr[op_start + 1] = PACKOPARG(ROT_TWO, 0);
+ fill_nops(codestr, op_start + 2, nexti + 1);
+ }
+ break;
+
+ /* Simplify conditional jump to conditional jump where the
+ result of the first test implies the success of a similar
+ test or the failure of the opposite test.
+ Arises in code like:
+ "a and b or c"
+ "(a and b) and c"
+ "(a or b) or c"
+ "(a or b) and c"
+ x:JUMP_IF_FALSE_OR_POP y y:JUMP_IF_FALSE_OR_POP z
+ --> x:JUMP_IF_FALSE_OR_POP z
+ x:JUMP_IF_FALSE_OR_POP y y:JUMP_IF_TRUE_OR_POP z
+ --> x:POP_JUMP_IF_FALSE y+1
+ where y+1 is the instruction following the second test.
+ */
+ case JUMP_IF_FALSE_OR_POP:
+ case JUMP_IF_TRUE_OR_POP:
+ h = get_arg(codestr, i) / sizeof(_Py_CODEUNIT);
+ tgt = find_op(codestr, codelen, h);
+
+ j = _Py_OPCODE(codestr[tgt]);
+ if (CONDITIONAL_JUMP(j)) {
+ /* NOTE: all possible jumps here are absolute. */
+ if (JUMPS_ON_TRUE(j) == JUMPS_ON_TRUE(opcode)) {
+ /* The second jump will be taken iff the first is.
+ The current opcode inherits its target's
+ stack effect */
+ h = set_arg(codestr, i, get_arg(codestr, tgt));
+ } else {
+ /* The second jump is not taken if the first is (so
+ jump past it), and all conditional jumps pop their
+ argument when they're not taken (so change the
+ first jump to pop its argument when it's taken). */
+ Py_ssize_t arg = (tgt + 1);
+ /* cannot overflow: codelen <= INT_MAX */
+ assert((size_t)arg <= UINT_MAX / sizeof(_Py_CODEUNIT));
+ arg *= sizeof(_Py_CODEUNIT);
+ h = set_arg(codestr, i, (unsigned int)arg);
+ j = opcode == JUMP_IF_TRUE_OR_POP ?
+ POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE;
+ }
+
+ if (h >= 0) {
+ nexti = h;
+ codestr[nexti] = PACKOPARG(j, _Py_OPARG(codestr[nexti]));
+ break;
+ }
+ }
+ /* Intentional fallthrough */
+
+ /* Replace jumps to unconditional jumps */
+ case POP_JUMP_IF_FALSE:
+ case POP_JUMP_IF_TRUE:
+ case JUMP_FORWARD:
+ case JUMP_ABSOLUTE:
+ h = GETJUMPTGT(codestr, i);
+ tgt = find_op(codestr, codelen, h);
+ /* Replace JUMP_* to a RETURN into just a RETURN */
+ if (UNCONDITIONAL_JUMP(opcode) &&
+ _Py_OPCODE(codestr[tgt]) == RETURN_VALUE) {
+ codestr[op_start] = PACKOPARG(RETURN_VALUE, 0);
+ fill_nops(codestr, op_start + 1, i + 1);
+ } else if (UNCONDITIONAL_JUMP(_Py_OPCODE(codestr[tgt]))) {
+ size_t arg = GETJUMPTGT(codestr, tgt);
+ if (opcode == JUMP_FORWARD) { /* JMP_ABS can go backwards */
+ opcode = JUMP_ABSOLUTE;
+ } else if (!ABSOLUTE_JUMP(opcode)) {
+ if (arg < (size_t)(i + 1)) {
+ break; /* No backward relative jumps */
+ }
+ arg -= i + 1; /* Calc relative jump addr */
+ }
+ /* cannot overflow: codelen <= INT_MAX */
+ assert(arg <= (UINT_MAX / sizeof(_Py_CODEUNIT)));
+ arg *= sizeof(_Py_CODEUNIT);
+ copy_op_arg(codestr, op_start, opcode,
+ (unsigned int)arg, i + 1);
+ }
+ break;
+
+ /* Remove unreachable ops after RETURN */
+ case RETURN_VALUE:
+ h = i + 1;
+ while (h < codelen && ISBASICBLOCK(blocks, i, h))
+ {
+ /* Leave SETUP_FINALLY and RERAISE in place to help find block limits. */
+ if (_Py_OPCODE(codestr[h]) == SETUP_FINALLY || _Py_OPCODE(codestr[h]) == RERAISE) {
+ while (h > i + 1 &&
+ _Py_OPCODE(codestr[h - 1]) == EXTENDED_ARG)
+ {
+ h--;
+ }
+ break;
+ }
+ h++;
+ }
+ if (h > i + 1) {
+ fill_nops(codestr, i + 1, h);
+ nexti = find_op(codestr, codelen, h);
+ }
+ break;
+ }
+ }
+
+ /* Fixup lnotab */
+ for (i = 0, nops = 0; i < codelen; i++) {
+ size_t block = (size_t)i - nops;
+ /* cannot overflow: codelen <= INT_MAX */
+ assert(block <= UINT_MAX);
+ /* original code offset => new code offset */
+ blocks[i] = (unsigned int)block;
+ if (_Py_OPCODE(codestr[i]) == NOP) {
+ nops++;
+ }
+ }
+ cum_orig_offset = 0;
+ last_offset = 0;
+ for (i=0 ; i < tabsiz ; i+=2) {
+ unsigned int offset_delta, new_offset;
+ cum_orig_offset += lnotab[i];
+ assert(cum_orig_offset % sizeof(_Py_CODEUNIT) == 0);
+ new_offset = blocks[cum_orig_offset / sizeof(_Py_CODEUNIT)] *
+ sizeof(_Py_CODEUNIT);
+ offset_delta = new_offset - last_offset;
+ assert(offset_delta <= 255);
+ lnotab[i] = (unsigned char)offset_delta;
+ last_offset = new_offset;
+ }
+
+ /* Remove NOPs and fixup jump targets */
+ for (op_start = i = h = 0; i < codelen; i++, op_start = i) {
+ j = _Py_OPARG(codestr[i]);
+ while (_Py_OPCODE(codestr[i]) == EXTENDED_ARG) {
+ i++;
+ j = j<<8 | _Py_OPARG(codestr[i]);
+ }
+ opcode = _Py_OPCODE(codestr[i]);
+ switch (opcode) {
+ case NOP:continue;
+
+ case JUMP_ABSOLUTE:
+ case POP_JUMP_IF_FALSE:
+ case POP_JUMP_IF_TRUE:
+ case JUMP_IF_FALSE_OR_POP:
+ case JUMP_IF_TRUE_OR_POP:
+ case JUMP_IF_NOT_EXC_MATCH:
+ j = blocks[j / sizeof(_Py_CODEUNIT)] * sizeof(_Py_CODEUNIT);
+ break;
+
+ case FOR_ITER:
+ case JUMP_FORWARD:
+ case SETUP_FINALLY:
+ case SETUP_WITH:
+ case SETUP_ASYNC_WITH:
+ j = blocks[j / sizeof(_Py_CODEUNIT) + i + 1] - blocks[i] - 1;
+ j *= sizeof(_Py_CODEUNIT);
+ break;
+ }
+ Py_ssize_t ilen = i - op_start + 1;
+ if (instrsize(j) > ilen) {
+ goto exitUnchanged;
+ }
+ /* If instrsize(j) < ilen, we'll emit EXTENDED_ARG 0 */
+ if (ilen > 4) {
+ /* Can only happen when PyCode_Optimize() is called with
+ malformed bytecode. */
+ goto exitUnchanged;
+ }
+ write_op_arg(codestr + h, opcode, j, (int)ilen);
+ h += ilen;
+ }
+ assert(h + (Py_ssize_t)nops == codelen);
+
+ PyMem_Free(blocks);
+ code = PyBytes_FromStringAndSize((char *)codestr, h * sizeof(_Py_CODEUNIT));
+ PyMem_Free(codestr);
+ return code;
+
+ exitError:
+ code = NULL;
+
+ exitUnchanged:
+ Py_XINCREF(code);
+ PyMem_Free(blocks);
+ PyMem_Free(codestr);
+ return code;
+}
diff --git a/contrib/tools/python3/src/Python/preconfig.c b/contrib/tools/python3/src/Python/preconfig.c
new file mode 100644
index 00000000000..262738fa57d
--- /dev/null
+++ b/contrib/tools/python3/src/Python/preconfig.c
@@ -0,0 +1,968 @@
+#include "Python.h"
+#include "pycore_getopt.h" // _PyOS_GetOpt()
+#include "pycore_initconfig.h" // _PyArgv
+#include "pycore_pymem.h" // _PyMem_GetAllocatorName()
+#include "pycore_runtime.h" // _PyRuntime_Initialize()
+#include <locale.h> // setlocale()
+
+
+#define DECODE_LOCALE_ERR(NAME, LEN) \
+ (((LEN) == -2) \
+ ? _PyStatus_ERR("cannot decode " NAME) \
+ : _PyStatus_NO_MEMORY())
+
+
+/* Forward declarations */
+static void
+preconfig_copy(PyPreConfig *config, const PyPreConfig *config2);
+
+
+/* --- File system encoding/errors -------------------------------- */
+
+/* The filesystem encoding is chosen by config_init_fs_encoding(),
+ see also initfsencoding().
+
+ Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors
+ are encoded to UTF-8. */
+const char *Py_FileSystemDefaultEncoding = NULL;
+int Py_HasFileSystemDefaultEncoding = 0;
+const char *Py_FileSystemDefaultEncodeErrors = NULL;
+int _Py_HasFileSystemDefaultEncodeErrors = 0;
+
+void
+_Py_ClearFileSystemEncoding(void)
+{
+ if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) {
+ PyMem_RawFree((char*)Py_FileSystemDefaultEncoding);
+ Py_FileSystemDefaultEncoding = NULL;
+ }
+ if (!_Py_HasFileSystemDefaultEncodeErrors && Py_FileSystemDefaultEncodeErrors) {
+ PyMem_RawFree((char*)Py_FileSystemDefaultEncodeErrors);
+ Py_FileSystemDefaultEncodeErrors = NULL;
+ }
+}
+
+
+/* Set Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors
+ global configuration variables. */
+int
+_Py_SetFileSystemEncoding(const char *encoding, const char *errors)
+{
+ char *encoding2 = _PyMem_RawStrdup(encoding);
+ if (encoding2 == NULL) {
+ return -1;
+ }
+
+ char *errors2 = _PyMem_RawStrdup(errors);
+ if (errors2 == NULL) {
+ PyMem_RawFree(encoding2);
+ return -1;
+ }
+
+ _Py_ClearFileSystemEncoding();
+
+ Py_FileSystemDefaultEncoding = encoding2;
+ Py_HasFileSystemDefaultEncoding = 0;
+
+ Py_FileSystemDefaultEncodeErrors = errors2;
+ _Py_HasFileSystemDefaultEncodeErrors = 0;
+ return 0;
+}
+
+
+/* --- _PyArgv ---------------------------------------------------- */
+
+/* Decode bytes_argv using Py_DecodeLocale() */
+PyStatus
+_PyArgv_AsWstrList(const _PyArgv *args, PyWideStringList *list)
+{
+ PyWideStringList wargv = _PyWideStringList_INIT;
+ if (args->use_bytes_argv) {
+ size_t size = sizeof(wchar_t*) * args->argc;
+ wargv.items = (wchar_t **)PyMem_RawMalloc(size);
+ if (wargv.items == NULL) {
+ return _PyStatus_NO_MEMORY();
+ }
+
+ for (Py_ssize_t i = 0; i < args->argc; i++) {
+ size_t len;
+ wchar_t *arg = Py_DecodeLocale(args->bytes_argv[i], &len);
+ if (arg == NULL) {
+ _PyWideStringList_Clear(&wargv);
+ return DECODE_LOCALE_ERR("command line arguments",
+ (Py_ssize_t)len);
+ }
+ wargv.items[i] = arg;
+ wargv.length++;
+ }
+
+ _PyWideStringList_Clear(list);
+ *list = wargv;
+ }
+ else {
+ wargv.length = args->argc;
+ wargv.items = (wchar_t **)args->wchar_argv;
+ if (_PyWideStringList_Copy(list, &wargv) < 0) {
+ return _PyStatus_NO_MEMORY();
+ }
+ }
+ return _PyStatus_OK();
+}
+
+
+/* --- _PyPreCmdline ------------------------------------------------- */
+
+void
+_PyPreCmdline_Clear(_PyPreCmdline *cmdline)
+{
+ _PyWideStringList_Clear(&cmdline->argv);
+ _PyWideStringList_Clear(&cmdline->xoptions);
+}
+
+
+PyStatus
+_PyPreCmdline_SetArgv(_PyPreCmdline *cmdline, const _PyArgv *args)
+{
+ return _PyArgv_AsWstrList(args, &cmdline->argv);
+}
+
+
+static void
+precmdline_get_preconfig(_PyPreCmdline *cmdline, const PyPreConfig *config)
+{
+#define COPY_ATTR(ATTR) \
+ if (config->ATTR != -1) { \
+ cmdline->ATTR = config->ATTR; \
+ }
+
+ COPY_ATTR(isolated);
+ COPY_ATTR(use_environment);
+ COPY_ATTR(dev_mode);
+
+#undef COPY_ATTR
+}
+
+
+static void
+precmdline_set_preconfig(const _PyPreCmdline *cmdline, PyPreConfig *config)
+{
+#define COPY_ATTR(ATTR) \
+ config->ATTR = cmdline->ATTR
+
+ COPY_ATTR(isolated);
+ COPY_ATTR(use_environment);
+ COPY_ATTR(dev_mode);
+
+#undef COPY_ATTR
+}
+
+
+PyStatus
+_PyPreCmdline_SetConfig(const _PyPreCmdline *cmdline, PyConfig *config)
+{
+#define COPY_ATTR(ATTR) \
+ config->ATTR = cmdline->ATTR
+
+ PyStatus status = _PyWideStringList_Extend(&config->xoptions, &cmdline->xoptions);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ COPY_ATTR(isolated);
+ COPY_ATTR(use_environment);
+ COPY_ATTR(dev_mode);
+ return _PyStatus_OK();
+
+#undef COPY_ATTR
+}
+
+
+/* Parse the command line arguments */
+static PyStatus
+precmdline_parse_cmdline(_PyPreCmdline *cmdline)
+{
+ const PyWideStringList *argv = &cmdline->argv;
+
+ _PyOS_ResetGetOpt();
+ /* Don't log parsing errors into stderr here: PyConfig_Read()
+ is responsible for that */
+ _PyOS_opterr = 0;
+ do {
+ int longindex = -1;
+ int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
+
+ if (c == EOF || c == 'c' || c == 'm') {
+ break;
+ }
+
+ switch (c) {
+ case 'E':
+ cmdline->use_environment = 0;
+ break;
+
+ case 'I':
+ cmdline->isolated = 1;
+ break;
+
+ case 'X':
+ {
+ PyStatus status = PyWideStringList_Append(&cmdline->xoptions,
+ _PyOS_optarg);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ break;
+ }
+
+ default:
+ /* ignore other argument:
+ handled by PyConfig_Read() */
+ break;
+ }
+ } while (1);
+
+ return _PyStatus_OK();
+}
+
+
+PyStatus
+_PyPreCmdline_Read(_PyPreCmdline *cmdline, const PyPreConfig *preconfig)
+{
+ precmdline_get_preconfig(cmdline, preconfig);
+
+ if (preconfig->parse_argv) {
+ PyStatus status = precmdline_parse_cmdline(cmdline);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ /* isolated, use_environment */
+ if (cmdline->isolated < 0) {
+ cmdline->isolated = 0;
+ }
+ if (cmdline->isolated > 0) {
+ cmdline->use_environment = 0;
+ }
+ if (cmdline->use_environment < 0) {
+ cmdline->use_environment = 0;
+ }
+
+ /* dev_mode */
+ if ((cmdline->dev_mode < 0)
+ && (_Py_get_xoption(&cmdline->xoptions, L"dev")
+ || _Py_GetEnv(cmdline->use_environment, "PYTHONDEVMODE")))
+ {
+ cmdline->dev_mode = 1;
+ }
+ if (cmdline->dev_mode < 0) {
+ cmdline->dev_mode = 0;
+ }
+
+ assert(cmdline->use_environment >= 0);
+ assert(cmdline->isolated >= 0);
+ assert(cmdline->dev_mode >= 0);
+
+ return _PyStatus_OK();
+}
+
+
+/* --- PyPreConfig ----------------------------------------------- */
+
+
+void
+_PyPreConfig_InitCompatConfig(PyPreConfig *config)
+{
+ memset(config, 0, sizeof(*config));
+
+ config->_config_init = (int)_PyConfig_INIT_COMPAT;
+ config->parse_argv = 0;
+ config->isolated = -1;
+ config->use_environment = -1;
+ config->configure_locale = 1;
+
+ /* bpo-36443: C locale coercion (PEP 538) and UTF-8 Mode (PEP 540)
+ are disabled by default using the Compat configuration.
+
+ Py_UTF8Mode=1 enables the UTF-8 mode. PYTHONUTF8 environment variable
+ is ignored (even if use_environment=1). */
+ config->utf8_mode = 0;
+ config->coerce_c_locale = 0;
+ config->coerce_c_locale_warn = 0;
+
+ config->dev_mode = -1;
+ config->allocator = PYMEM_ALLOCATOR_NOT_SET;
+#ifdef MS_WINDOWS
+ config->legacy_windows_fs_encoding = -1;
+#endif
+}
+
+
+void
+PyPreConfig_InitPythonConfig(PyPreConfig *config)
+{
+ _PyPreConfig_InitCompatConfig(config);
+
+ config->_config_init = (int)_PyConfig_INIT_PYTHON;
+ config->isolated = 0;
+ config->parse_argv = 1;
+ config->use_environment = 1;
+ /* Set to -1 to enable C locale coercion (PEP 538) and UTF-8 Mode (PEP 540)
+ depending on the LC_CTYPE locale, PYTHONUTF8 and PYTHONCOERCECLOCALE
+ environment variables. */
+ config->coerce_c_locale = -1;
+ config->coerce_c_locale_warn = -1;
+ config->utf8_mode = -1;
+#ifdef MS_WINDOWS
+ config->legacy_windows_fs_encoding = 0;
+#endif
+}
+
+
+void
+PyPreConfig_InitIsolatedConfig(PyPreConfig *config)
+{
+ _PyPreConfig_InitCompatConfig(config);
+
+ config->_config_init = (int)_PyConfig_INIT_ISOLATED;
+ config->configure_locale = 0;
+ config->isolated = 1;
+ config->use_environment = 0;
+ config->utf8_mode = 0;
+ config->dev_mode = 0;
+#ifdef MS_WINDOWS
+ config->legacy_windows_fs_encoding = 0;
+#endif
+}
+
+
+PyStatus
+_PyPreConfig_InitFromPreConfig(PyPreConfig *config,
+ const PyPreConfig *config2)
+{
+ PyPreConfig_InitPythonConfig(config);
+ preconfig_copy(config, config2);
+ return _PyStatus_OK();
+}
+
+
+void
+_PyPreConfig_InitFromConfig(PyPreConfig *preconfig, const PyConfig *config)
+{
+ _PyConfigInitEnum config_init = (_PyConfigInitEnum)config->_config_init;
+ switch (config_init) {
+ case _PyConfig_INIT_PYTHON:
+ PyPreConfig_InitPythonConfig(preconfig);
+ break;
+ case _PyConfig_INIT_ISOLATED:
+ PyPreConfig_InitIsolatedConfig(preconfig);
+ break;
+ case _PyConfig_INIT_COMPAT:
+ default:
+ _PyPreConfig_InitCompatConfig(preconfig);
+ }
+
+ _PyPreConfig_GetConfig(preconfig, config);
+}
+
+
+static void
+preconfig_copy(PyPreConfig *config, const PyPreConfig *config2)
+{
+#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
+
+ COPY_ATTR(_config_init);
+ COPY_ATTR(parse_argv);
+ COPY_ATTR(isolated);
+ COPY_ATTR(use_environment);
+ COPY_ATTR(configure_locale);
+ COPY_ATTR(dev_mode);
+ COPY_ATTR(coerce_c_locale);
+ COPY_ATTR(coerce_c_locale_warn);
+ COPY_ATTR(utf8_mode);
+ COPY_ATTR(allocator);
+#ifdef MS_WINDOWS
+ COPY_ATTR(legacy_windows_fs_encoding);
+#endif
+
+#undef COPY_ATTR
+}
+
+
+PyObject*
+_PyPreConfig_AsDict(const PyPreConfig *config)
+{
+ PyObject *dict;
+
+ dict = PyDict_New();
+ if (dict == NULL) {
+ return NULL;
+ }
+
+#define SET_ITEM_INT(ATTR) \
+ do { \
+ PyObject *obj = PyLong_FromLong(config->ATTR); \
+ if (obj == NULL) { \
+ goto fail; \
+ } \
+ int res = PyDict_SetItemString(dict, #ATTR, obj); \
+ Py_DECREF(obj); \
+ if (res < 0) { \
+ goto fail; \
+ } \
+ } while (0)
+
+ SET_ITEM_INT(_config_init);
+ SET_ITEM_INT(parse_argv);
+ SET_ITEM_INT(isolated);
+ SET_ITEM_INT(use_environment);
+ SET_ITEM_INT(configure_locale);
+ SET_ITEM_INT(coerce_c_locale);
+ SET_ITEM_INT(coerce_c_locale_warn);
+ SET_ITEM_INT(utf8_mode);
+#ifdef MS_WINDOWS
+ SET_ITEM_INT(legacy_windows_fs_encoding);
+#endif
+ SET_ITEM_INT(dev_mode);
+ SET_ITEM_INT(allocator);
+ return dict;
+
+fail:
+ Py_DECREF(dict);
+ return NULL;
+
+#undef SET_ITEM_INT
+}
+
+
+void
+_PyPreConfig_GetConfig(PyPreConfig *preconfig, const PyConfig *config)
+{
+#define COPY_ATTR(ATTR) \
+ if (config->ATTR != -1) { \
+ preconfig->ATTR = config->ATTR; \
+ }
+
+ COPY_ATTR(parse_argv);
+ COPY_ATTR(isolated);
+ COPY_ATTR(use_environment);
+ COPY_ATTR(dev_mode);
+
+#undef COPY_ATTR
+}
+
+
+static void
+preconfig_get_global_vars(PyPreConfig *config)
+{
+ if (config->_config_init != _PyConfig_INIT_COMPAT) {
+ /* Python and Isolated configuration ignore global variables */
+ return;
+ }
+
+#define COPY_FLAG(ATTR, VALUE) \
+ if (config->ATTR < 0) { \
+ config->ATTR = VALUE; \
+ }
+#define COPY_NOT_FLAG(ATTR, VALUE) \
+ if (config->ATTR < 0) { \
+ config->ATTR = !(VALUE); \
+ }
+
+ COPY_FLAG(isolated, Py_IsolatedFlag);
+ COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
+ if (Py_UTF8Mode > 0) {
+ config->utf8_mode = Py_UTF8Mode;
+ }
+#ifdef MS_WINDOWS
+ COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag);
+#endif
+
+#undef COPY_FLAG
+#undef COPY_NOT_FLAG
+}
+
+
+static void
+preconfig_set_global_vars(const PyPreConfig *config)
+{
+#define COPY_FLAG(ATTR, VAR) \
+ if (config->ATTR >= 0) { \
+ VAR = config->ATTR; \
+ }
+#define COPY_NOT_FLAG(ATTR, VAR) \
+ if (config->ATTR >= 0) { \
+ VAR = !config->ATTR; \
+ }
+
+ COPY_FLAG(isolated, Py_IsolatedFlag);
+ COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
+#ifdef MS_WINDOWS
+ COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag);
+#endif
+ COPY_FLAG(utf8_mode, Py_UTF8Mode);
+
+#undef COPY_FLAG
+#undef COPY_NOT_FLAG
+}
+
+
+const char*
+_Py_GetEnv(int use_environment, const char *name)
+{
+ assert(use_environment >= 0);
+
+ if (!use_environment) {
+ return NULL;
+ }
+
+ const char *var = getenv(name);
+ if (var && var[0] != '\0') {
+ return var;
+ }
+ else {
+ return NULL;
+ }
+}
+
+
+int
+_Py_str_to_int(const char *str, int *result)
+{
+ const char *endptr = str;
+ errno = 0;
+ long value = strtol(str, (char **)&endptr, 10);
+ if (*endptr != '\0' || errno == ERANGE) {
+ return -1;
+ }
+ if (value < INT_MIN || value > INT_MAX) {
+ return -1;
+ }
+
+ *result = (int)value;
+ return 0;
+}
+
+
+void
+_Py_get_env_flag(int use_environment, int *flag, const char *name)
+{
+ const char *var = _Py_GetEnv(use_environment, name);
+ if (!var) {
+ return;
+ }
+ int value;
+ if (_Py_str_to_int(var, &value) < 0 || value < 0) {
+ /* PYTHONDEBUG=text and PYTHONDEBUG=-2 behave as PYTHONDEBUG=1 */
+ value = 1;
+ }
+ if (*flag < value) {
+ *flag = value;
+ }
+}
+
+
+const wchar_t*
+_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'=');
+ if (sep != NULL) {
+ len = (sep - option);
+ }
+ else {
+ len = wcslen(option);
+ }
+ if (wcsncmp(option, name, len) == 0 && name[len] == L'\0') {
+ return option;
+ }
+ }
+ return NULL;
+}
+
+
+static PyStatus
+preconfig_init_utf8_mode(PyPreConfig *config, const _PyPreCmdline *cmdline)
+{
+#ifdef MS_WINDOWS
+ if (config->legacy_windows_fs_encoding) {
+ config->utf8_mode = 0;
+ }
+#endif
+
+ if (config->utf8_mode >= 0) {
+ return _PyStatus_OK();
+ }
+
+ const wchar_t *xopt;
+ xopt = _Py_get_xoption(&cmdline->xoptions, L"utf8");
+ if (xopt) {
+ wchar_t *sep = wcschr(xopt, L'=');
+ if (sep) {
+ xopt = sep + 1;
+ if (wcscmp(xopt, L"1") == 0) {
+ config->utf8_mode = 1;
+ }
+ else if (wcscmp(xopt, L"0") == 0) {
+ config->utf8_mode = 0;
+ }
+ else {
+ return _PyStatus_ERR("invalid -X utf8 option value");
+ }
+ }
+ else {
+ config->utf8_mode = 1;
+ }
+ return _PyStatus_OK();
+ }
+
+ const char *opt = _Py_GetEnv(config->use_environment, "PYTHONUTF8");
+ if (opt) {
+ if (strcmp(opt, "1") == 0) {
+ config->utf8_mode = 1;
+ }
+ else if (strcmp(opt, "0") == 0) {
+ config->utf8_mode = 0;
+ }
+ else {
+ return _PyStatus_ERR("invalid PYTHONUTF8 environment "
+ "variable value");
+ }
+ return _PyStatus_OK();
+ }
+
+
+#ifndef MS_WINDOWS
+ if (config->utf8_mode < 0) {
+ /* The C locale and the POSIX locale enable the UTF-8 Mode (PEP 540) */
+ const char *ctype_loc = setlocale(LC_CTYPE, NULL);
+ if (ctype_loc != NULL
+ && (strcmp(ctype_loc, "C") == 0
+ || strcmp(ctype_loc, "POSIX") == 0))
+ {
+ config->utf8_mode = 1;
+ }
+ }
+#endif
+
+ if (config->utf8_mode < 0) {
+ config->utf8_mode = 0;
+ }
+ return _PyStatus_OK();
+}
+
+
+static void
+preconfig_init_coerce_c_locale(PyPreConfig *config)
+{
+ if (!config->configure_locale) {
+ config->coerce_c_locale = 0;
+ config->coerce_c_locale_warn = 0;
+ return;
+ }
+
+ const char *env = _Py_GetEnv(config->use_environment, "PYTHONCOERCECLOCALE");
+ if (env) {
+ if (strcmp(env, "0") == 0) {
+ if (config->coerce_c_locale < 0) {
+ config->coerce_c_locale = 0;
+ }
+ }
+ else if (strcmp(env, "warn") == 0) {
+ if (config->coerce_c_locale_warn < 0) {
+ config->coerce_c_locale_warn = 1;
+ }
+ }
+ else {
+ if (config->coerce_c_locale < 0) {
+ config->coerce_c_locale = 1;
+ }
+ }
+ }
+
+ /* Test if coerce_c_locale equals to -1 or equals to 1:
+ PYTHONCOERCECLOCALE=1 doesn't imply that the C locale is always coerced.
+ It is only coerced if if the LC_CTYPE locale is "C". */
+ if (config->coerce_c_locale < 0 || config->coerce_c_locale == 1) {
+ /* The C locale enables the C locale coercion (PEP 538) */
+ if (_Py_LegacyLocaleDetected(0)) {
+ config->coerce_c_locale = 2;
+ }
+ else {
+ config->coerce_c_locale = 0;
+ }
+ }
+
+ if (config->coerce_c_locale_warn < 0) {
+ config->coerce_c_locale_warn = 0;
+ }
+}
+
+
+static PyStatus
+preconfig_init_allocator(PyPreConfig *config)
+{
+ if (config->allocator == PYMEM_ALLOCATOR_NOT_SET) {
+ /* bpo-34247. The PYTHONMALLOC environment variable has the priority
+ over PYTHONDEV env var and "-X dev" command line option.
+ For example, PYTHONMALLOC=malloc PYTHONDEVMODE=1 sets the memory
+ allocators to "malloc" (and not to "debug"). */
+ const char *envvar = _Py_GetEnv(config->use_environment, "PYTHONMALLOC");
+ if (envvar) {
+ PyMemAllocatorName name;
+ if (_PyMem_GetAllocatorName(envvar, &name) < 0) {
+ return _PyStatus_ERR("PYTHONMALLOC: unknown allocator");
+ }
+ config->allocator = (int)name;
+ }
+ }
+
+ if (config->dev_mode && config->allocator == PYMEM_ALLOCATOR_NOT_SET) {
+ config->allocator = PYMEM_ALLOCATOR_DEBUG;
+ }
+ return _PyStatus_OK();
+}
+
+
+static PyStatus
+preconfig_read(PyPreConfig *config, _PyPreCmdline *cmdline)
+{
+ PyStatus status;
+
+ status = _PyPreCmdline_Read(cmdline, config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ precmdline_set_preconfig(cmdline, config);
+
+ /* legacy_windows_fs_encoding, coerce_c_locale, utf8_mode */
+#ifdef MS_WINDOWS
+ _Py_get_env_flag(config->use_environment,
+ &config->legacy_windows_fs_encoding,
+ "PYTHONLEGACYWINDOWSFSENCODING");
+#endif
+
+ preconfig_init_coerce_c_locale(config);
+
+ status = preconfig_init_utf8_mode(config, cmdline);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ /* allocator */
+ status = preconfig_init_allocator(config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ assert(config->coerce_c_locale >= 0);
+ assert(config->coerce_c_locale_warn >= 0);
+#ifdef MS_WINDOWS
+ assert(config->legacy_windows_fs_encoding >= 0);
+#endif
+ assert(config->utf8_mode >= 0);
+ assert(config->isolated >= 0);
+ assert(config->use_environment >= 0);
+ assert(config->dev_mode >= 0);
+
+ return _PyStatus_OK();
+}
+
+
+/* Read the configuration from:
+
+ - command line arguments
+ - environment variables
+ - Py_xxx global configuration variables
+ - the LC_CTYPE locale */
+PyStatus
+_PyPreConfig_Read(PyPreConfig *config, const _PyArgv *args)
+{
+ PyStatus status;
+
+ status = _PyRuntime_Initialize();
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ preconfig_get_global_vars(config);
+
+ /* Copy LC_CTYPE locale, since it's modified later */
+ const char *loc = setlocale(LC_CTYPE, NULL);
+ if (loc == NULL) {
+ return _PyStatus_ERR("failed to LC_CTYPE locale");
+ }
+ char *init_ctype_locale = _PyMem_RawStrdup(loc);
+ if (init_ctype_locale == NULL) {
+ return _PyStatus_NO_MEMORY();
+ }
+
+ /* Save the config to be able to restore it if encodings change */
+ PyPreConfig save_config;
+
+ status = _PyPreConfig_InitFromPreConfig(&save_config, config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ /* Set LC_CTYPE to the user preferred locale */
+ if (config->configure_locale) {
+ _Py_SetLocaleFromEnv(LC_CTYPE);
+ }
+
+ _PyPreCmdline cmdline = _PyPreCmdline_INIT;
+ int init_utf8_mode = Py_UTF8Mode;
+#ifdef MS_WINDOWS
+ int init_legacy_encoding = Py_LegacyWindowsFSEncodingFlag;
+#endif
+
+ if (args) {
+ status = _PyPreCmdline_SetArgv(&cmdline, args);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+ }
+
+ int locale_coerced = 0;
+ int loops = 0;
+
+ while (1) {
+ int utf8_mode = config->utf8_mode;
+
+ /* Watchdog to prevent an infinite loop */
+ loops++;
+ if (loops == 3) {
+ status = _PyStatus_ERR("Encoding changed twice while "
+ "reading the configuration");
+ goto done;
+ }
+
+ /* bpo-34207: Py_DecodeLocale() and Py_EncodeLocale() depend
+ on Py_UTF8Mode and Py_LegacyWindowsFSEncodingFlag. */
+ Py_UTF8Mode = config->utf8_mode;
+#ifdef MS_WINDOWS
+ Py_LegacyWindowsFSEncodingFlag = config->legacy_windows_fs_encoding;
+#endif
+
+ status = preconfig_read(config, &cmdline);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+
+ /* The legacy C locale assumes ASCII as the default text encoding, which
+ * causes problems not only for the CPython runtime, but also other
+ * components like GNU readline.
+ *
+ * Accordingly, when the CLI detects it, it attempts to coerce it to a
+ * more capable UTF-8 based alternative.
+ *
+ * See the documentation of the PYTHONCOERCECLOCALE setting for more
+ * details.
+ */
+ int encoding_changed = 0;
+ if (config->coerce_c_locale && !locale_coerced) {
+ locale_coerced = 1;
+ _Py_CoerceLegacyLocale(0);
+ encoding_changed = 1;
+ }
+
+ if (utf8_mode == -1) {
+ if (config->utf8_mode == 1) {
+ /* UTF-8 Mode enabled */
+ encoding_changed = 1;
+ }
+ }
+ else {
+ if (config->utf8_mode != utf8_mode) {
+ encoding_changed = 1;
+ }
+ }
+
+ if (!encoding_changed) {
+ break;
+ }
+
+ /* Reset the configuration before reading again the configuration,
+ just keep UTF-8 Mode value. */
+ int new_utf8_mode = config->utf8_mode;
+ int new_coerce_c_locale = config->coerce_c_locale;
+ preconfig_copy(config, &save_config);
+ config->utf8_mode = new_utf8_mode;
+ config->coerce_c_locale = new_coerce_c_locale;
+
+ /* The encoding changed: read again the configuration
+ with the new encoding */
+ }
+ status = _PyStatus_OK();
+
+done:
+ if (init_ctype_locale != NULL) {
+ setlocale(LC_CTYPE, init_ctype_locale);
+ PyMem_RawFree(init_ctype_locale);
+ }
+ Py_UTF8Mode = init_utf8_mode ;
+#ifdef MS_WINDOWS
+ Py_LegacyWindowsFSEncodingFlag = init_legacy_encoding;
+#endif
+ _PyPreCmdline_Clear(&cmdline);
+ return status;
+}
+
+
+/* Write the pre-configuration:
+
+ - set the memory allocators
+ - set Py_xxx global configuration variables
+ - set the LC_CTYPE locale (coerce C locale, PEP 538) and set the UTF-8 mode
+ (PEP 540)
+
+ The applied configuration is written into _PyRuntime.preconfig.
+ If the C locale cannot be coerced, set coerce_c_locale to 0.
+
+ Do nothing if called after Py_Initialize(): ignore the new
+ pre-configuration. */
+PyStatus
+_PyPreConfig_Write(const PyPreConfig *src_config)
+{
+ PyPreConfig config;
+
+ PyStatus status = _PyPreConfig_InitFromPreConfig(&config, src_config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ if (_PyRuntime.core_initialized) {
+ /* bpo-34008: Calling this functions after Py_Initialize() ignores
+ the new configuration. */
+ return _PyStatus_OK();
+ }
+
+ PyMemAllocatorName name = (PyMemAllocatorName)config.allocator;
+ if (name != PYMEM_ALLOCATOR_NOT_SET) {
+ if (_PyMem_SetupAllocators(name) < 0) {
+ return _PyStatus_ERR("Unknown PYTHONMALLOC allocator");
+ }
+ }
+
+ preconfig_set_global_vars(&config);
+
+ if (config.configure_locale) {
+ if (config.coerce_c_locale) {
+ if (!_Py_CoerceLegacyLocale(config.coerce_c_locale_warn)) {
+ /* C locale not coerced */
+ config.coerce_c_locale = 0;
+ }
+ }
+
+ /* Set LC_CTYPE to the user preferred locale */
+ _Py_SetLocaleFromEnv(LC_CTYPE);
+ }
+
+ /* Write the new pre-configuration into _PyRuntime */
+ preconfig_copy(&_PyRuntime.preconfig, &config);
+
+ return _PyStatus_OK();
+}
diff --git a/contrib/tools/python3/src/Python/pyarena.c b/contrib/tools/python3/src/Python/pyarena.c
new file mode 100644
index 00000000000..aefb787e554
--- /dev/null
+++ b/contrib/tools/python3/src/Python/pyarena.c
@@ -0,0 +1,210 @@
+#include "Python.h"
+
+/* A simple arena block structure.
+
+ Measurements with standard library modules suggest the average
+ allocation is about 20 bytes and that most compiles use a single
+ block.
+
+ TODO(jhylton): Think about a realloc API, maybe just for the last
+ allocation?
+*/
+
+#define DEFAULT_BLOCK_SIZE 8192
+#define ALIGNMENT 8
+
+typedef struct _block {
+ /* Total number of bytes owned by this block available to pass out.
+ * Read-only after initialization. The first such byte starts at
+ * ab_mem.
+ */
+ size_t ab_size;
+
+ /* Total number of bytes already passed out. The next byte available
+ * to pass out starts at ab_mem + ab_offset.
+ */
+ size_t ab_offset;
+
+ /* An arena maintains a singly-linked, NULL-terminated list of
+ * all blocks owned by the arena. These are linked via the
+ * ab_next member.
+ */
+ struct _block *ab_next;
+
+ /* Pointer to the first allocatable byte owned by this block. Read-
+ * only after initialization.
+ */
+ void *ab_mem;
+} block;
+
+/* The arena manages two kinds of memory, blocks of raw memory
+ and a list of PyObject* pointers. PyObjects are decrefed
+ when the arena is freed.
+*/
+
+struct _arena {
+ /* Pointer to the first block allocated for the arena, never NULL.
+ It is used only to find the first block when the arena is
+ being freed.
+ */
+ block *a_head;
+
+ /* Pointer to the block currently used for allocation. Its
+ ab_next field should be NULL. If it is not-null after a
+ call to block_alloc(), it means a new block has been allocated
+ and a_cur should be reset to point it.
+ */
+ block *a_cur;
+
+ /* A Python list object containing references to all the PyObject
+ pointers associated with this arena. They will be DECREFed
+ when the arena is freed.
+ */
+ PyObject *a_objects;
+
+#if defined(Py_DEBUG)
+ /* Debug output */
+ size_t total_allocs;
+ size_t total_size;
+ size_t total_blocks;
+ size_t total_block_size;
+ size_t total_big_blocks;
+#endif
+};
+
+static block *
+block_new(size_t size)
+{
+ /* Allocate header and block as one unit.
+ ab_mem points just past header. */
+ block *b = (block *)PyMem_Malloc(sizeof(block) + size);
+ if (!b)
+ return NULL;
+ b->ab_size = size;
+ b->ab_mem = (void *)(b + 1);
+ b->ab_next = NULL;
+ b->ab_offset = (char *)_Py_ALIGN_UP(b->ab_mem, ALIGNMENT) -
+ (char *)(b->ab_mem);
+ return b;
+}
+
+static void
+block_free(block *b) {
+ while (b) {
+ block *next = b->ab_next;
+ PyMem_Free(b);
+ b = next;
+ }
+}
+
+static void *
+block_alloc(block *b, size_t size)
+{
+ void *p;
+ assert(b);
+ size = _Py_SIZE_ROUND_UP(size, ALIGNMENT);
+ if (b->ab_offset + size > b->ab_size) {
+ /* If we need to allocate more memory than will fit in
+ the default block, allocate a one-off block that is
+ exactly the right size. */
+ /* TODO(jhylton): Think about space waste at end of block */
+ block *newbl = block_new(
+ size < DEFAULT_BLOCK_SIZE ?
+ DEFAULT_BLOCK_SIZE : size);
+ if (!newbl)
+ return NULL;
+ assert(!b->ab_next);
+ b->ab_next = newbl;
+ b = newbl;
+ }
+
+ assert(b->ab_offset + size <= b->ab_size);
+ p = (void *)(((char *)b->ab_mem) + b->ab_offset);
+ b->ab_offset += size;
+ return p;
+}
+
+PyArena *
+PyArena_New()
+{
+ PyArena* arena = (PyArena *)PyMem_Malloc(sizeof(PyArena));
+ if (!arena)
+ return (PyArena*)PyErr_NoMemory();
+
+ arena->a_head = block_new(DEFAULT_BLOCK_SIZE);
+ arena->a_cur = arena->a_head;
+ if (!arena->a_head) {
+ PyMem_Free((void *)arena);
+ return (PyArena*)PyErr_NoMemory();
+ }
+ arena->a_objects = PyList_New(0);
+ if (!arena->a_objects) {
+ block_free(arena->a_head);
+ PyMem_Free((void *)arena);
+ return (PyArena*)PyErr_NoMemory();
+ }
+#if defined(Py_DEBUG)
+ arena->total_allocs = 0;
+ arena->total_size = 0;
+ arena->total_blocks = 1;
+ arena->total_block_size = DEFAULT_BLOCK_SIZE;
+ arena->total_big_blocks = 0;
+#endif
+ return arena;
+}
+
+void
+PyArena_Free(PyArena *arena)
+{
+ assert(arena);
+#if defined(Py_DEBUG)
+ /*
+ fprintf(stderr,
+ "alloc=%zu size=%zu blocks=%zu block_size=%zu big=%zu objects=%zu\n",
+ arena->total_allocs, arena->total_size, arena->total_blocks,
+ arena->total_block_size, arena->total_big_blocks,
+ PyList_Size(arena->a_objects));
+ */
+#endif
+ block_free(arena->a_head);
+ /* This property normally holds, except when the code being compiled
+ is sys.getobjects(0), in which case there will be two references.
+ assert(arena->a_objects->ob_refcnt == 1);
+ */
+
+ Py_DECREF(arena->a_objects);
+ PyMem_Free(arena);
+}
+
+void *
+PyArena_Malloc(PyArena *arena, size_t size)
+{
+ void *p = block_alloc(arena->a_cur, size);
+ if (!p)
+ return PyErr_NoMemory();
+#if defined(Py_DEBUG)
+ arena->total_allocs++;
+ arena->total_size += size;
+#endif
+ /* Reset cur if we allocated a new block. */
+ if (arena->a_cur->ab_next) {
+ arena->a_cur = arena->a_cur->ab_next;
+#if defined(Py_DEBUG)
+ arena->total_blocks++;
+ arena->total_block_size += arena->a_cur->ab_size;
+ if (arena->a_cur->ab_size > DEFAULT_BLOCK_SIZE)
+ ++arena->total_big_blocks;
+#endif
+ }
+ return p;
+}
+
+int
+PyArena_AddPyObject(PyArena *arena, PyObject *obj)
+{
+ int r = PyList_Append(arena->a_objects, obj);
+ if (r >= 0) {
+ Py_DECREF(obj);
+ }
+ return r;
+}
diff --git a/contrib/tools/python3/src/Python/pyctype.c b/contrib/tools/python3/src/Python/pyctype.c
new file mode 100644
index 00000000000..da117d58fd0
--- /dev/null
+++ b/contrib/tools/python3/src/Python/pyctype.c
@@ -0,0 +1,214 @@
+#include "Python.h"
+
+/* Our own locale-independent ctype.h-like macros */
+
+const unsigned int _Py_ctype_table[256] = {
+ 0, /* 0x0 '\x00' */
+ 0, /* 0x1 '\x01' */
+ 0, /* 0x2 '\x02' */
+ 0, /* 0x3 '\x03' */
+ 0, /* 0x4 '\x04' */
+ 0, /* 0x5 '\x05' */
+ 0, /* 0x6 '\x06' */
+ 0, /* 0x7 '\x07' */
+ 0, /* 0x8 '\x08' */
+ PY_CTF_SPACE, /* 0x9 '\t' */
+ PY_CTF_SPACE, /* 0xa '\n' */
+ PY_CTF_SPACE, /* 0xb '\v' */
+ PY_CTF_SPACE, /* 0xc '\f' */
+ PY_CTF_SPACE, /* 0xd '\r' */
+ 0, /* 0xe '\x0e' */
+ 0, /* 0xf '\x0f' */
+ 0, /* 0x10 '\x10' */
+ 0, /* 0x11 '\x11' */
+ 0, /* 0x12 '\x12' */
+ 0, /* 0x13 '\x13' */
+ 0, /* 0x14 '\x14' */
+ 0, /* 0x15 '\x15' */
+ 0, /* 0x16 '\x16' */
+ 0, /* 0x17 '\x17' */
+ 0, /* 0x18 '\x18' */
+ 0, /* 0x19 '\x19' */
+ 0, /* 0x1a '\x1a' */
+ 0, /* 0x1b '\x1b' */
+ 0, /* 0x1c '\x1c' */
+ 0, /* 0x1d '\x1d' */
+ 0, /* 0x1e '\x1e' */
+ 0, /* 0x1f '\x1f' */
+ PY_CTF_SPACE, /* 0x20 ' ' */
+ 0, /* 0x21 '!' */
+ 0, /* 0x22 '"' */
+ 0, /* 0x23 '#' */
+ 0, /* 0x24 '$' */
+ 0, /* 0x25 '%' */
+ 0, /* 0x26 '&' */
+ 0, /* 0x27 "'" */
+ 0, /* 0x28 '(' */
+ 0, /* 0x29 ')' */
+ 0, /* 0x2a '*' */
+ 0, /* 0x2b '+' */
+ 0, /* 0x2c ',' */
+ 0, /* 0x2d '-' */
+ 0, /* 0x2e '.' */
+ 0, /* 0x2f '/' */
+ PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x30 '0' */
+ PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x31 '1' */
+ PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x32 '2' */
+ PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x33 '3' */
+ PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x34 '4' */
+ PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x35 '5' */
+ PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x36 '6' */
+ PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x37 '7' */
+ PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x38 '8' */
+ PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x39 '9' */
+ 0, /* 0x3a ':' */
+ 0, /* 0x3b ';' */
+ 0, /* 0x3c '<' */
+ 0, /* 0x3d '=' */
+ 0, /* 0x3e '>' */
+ 0, /* 0x3f '?' */
+ 0, /* 0x40 '@' */
+ PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x41 'A' */
+ PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x42 'B' */
+ PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x43 'C' */
+ PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x44 'D' */
+ PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x45 'E' */
+ PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x46 'F' */
+ PY_CTF_UPPER, /* 0x47 'G' */
+ PY_CTF_UPPER, /* 0x48 'H' */
+ PY_CTF_UPPER, /* 0x49 'I' */
+ PY_CTF_UPPER, /* 0x4a 'J' */
+ PY_CTF_UPPER, /* 0x4b 'K' */
+ PY_CTF_UPPER, /* 0x4c 'L' */
+ PY_CTF_UPPER, /* 0x4d 'M' */
+ PY_CTF_UPPER, /* 0x4e 'N' */
+ PY_CTF_UPPER, /* 0x4f 'O' */
+ PY_CTF_UPPER, /* 0x50 'P' */
+ PY_CTF_UPPER, /* 0x51 'Q' */
+ PY_CTF_UPPER, /* 0x52 'R' */
+ PY_CTF_UPPER, /* 0x53 'S' */
+ PY_CTF_UPPER, /* 0x54 'T' */
+ PY_CTF_UPPER, /* 0x55 'U' */
+ PY_CTF_UPPER, /* 0x56 'V' */
+ PY_CTF_UPPER, /* 0x57 'W' */
+ PY_CTF_UPPER, /* 0x58 'X' */
+ PY_CTF_UPPER, /* 0x59 'Y' */
+ PY_CTF_UPPER, /* 0x5a 'Z' */
+ 0, /* 0x5b '[' */
+ 0, /* 0x5c '\\' */
+ 0, /* 0x5d ']' */
+ 0, /* 0x5e '^' */
+ 0, /* 0x5f '_' */
+ 0, /* 0x60 '`' */
+ PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x61 'a' */
+ PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x62 'b' */
+ PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x63 'c' */
+ PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x64 'd' */
+ PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x65 'e' */
+ PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x66 'f' */
+ PY_CTF_LOWER, /* 0x67 'g' */
+ PY_CTF_LOWER, /* 0x68 'h' */
+ PY_CTF_LOWER, /* 0x69 'i' */
+ PY_CTF_LOWER, /* 0x6a 'j' */
+ PY_CTF_LOWER, /* 0x6b 'k' */
+ PY_CTF_LOWER, /* 0x6c 'l' */
+ PY_CTF_LOWER, /* 0x6d 'm' */
+ PY_CTF_LOWER, /* 0x6e 'n' */
+ PY_CTF_LOWER, /* 0x6f 'o' */
+ PY_CTF_LOWER, /* 0x70 'p' */
+ PY_CTF_LOWER, /* 0x71 'q' */
+ PY_CTF_LOWER, /* 0x72 'r' */
+ PY_CTF_LOWER, /* 0x73 's' */
+ PY_CTF_LOWER, /* 0x74 't' */
+ PY_CTF_LOWER, /* 0x75 'u' */
+ PY_CTF_LOWER, /* 0x76 'v' */
+ PY_CTF_LOWER, /* 0x77 'w' */
+ PY_CTF_LOWER, /* 0x78 'x' */
+ PY_CTF_LOWER, /* 0x79 'y' */
+ PY_CTF_LOWER, /* 0x7a 'z' */
+ 0, /* 0x7b '{' */
+ 0, /* 0x7c '|' */
+ 0, /* 0x7d '}' */
+ 0, /* 0x7e '~' */
+ 0, /* 0x7f '\x7f' */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+
+const unsigned char _Py_ctype_tolower[256] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+};
+
+const unsigned char _Py_ctype_toupper[256] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+};
+
diff --git a/contrib/tools/python3/src/Python/pyfpe.c b/contrib/tools/python3/src/Python/pyfpe.c
new file mode 100644
index 00000000000..31ef5d73b70
--- /dev/null
+++ b/contrib/tools/python3/src/Python/pyfpe.c
@@ -0,0 +1,15 @@
+/* These variables used to be used when Python was built with --with-fpectl,
+ * but support for that was dropped in 3.7. We continue to define them,
+ * though, because they may be referenced by extensions using the stable ABI.
+ */
+
+#include "setjmp.h"
+
+jmp_buf PyFPE_jbuf;
+int PyFPE_counter;
+
+double
+PyFPE_dummy(void *dummy)
+{
+ return 1.0;
+}
diff --git a/contrib/tools/python3/src/Python/pyhash.c b/contrib/tools/python3/src/Python/pyhash.c
new file mode 100644
index 00000000000..3843079fbbc
--- /dev/null
+++ b/contrib/tools/python3/src/Python/pyhash.c
@@ -0,0 +1,441 @@
+/* Set of hash utility functions to help maintaining the invariant that
+ if a==b then hash(a)==hash(b)
+
+ All the utility functions (_Py_Hash*()) return "-1" to signify an error.
+*/
+#include "Python.h"
+
+#ifdef __APPLE__
+# include <libkern/OSByteOrder.h>
+#elif defined(HAVE_LE64TOH) && defined(HAVE_ENDIAN_H)
+# include <endian.h>
+#elif defined(HAVE_LE64TOH) && defined(HAVE_SYS_ENDIAN_H)
+# include <sys/endian.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_Py_HashSecret_t _Py_HashSecret = {{0}};
+
+#if Py_HASH_ALGORITHM == Py_HASH_EXTERNAL
+extern PyHash_FuncDef PyHash_Func;
+#else
+static PyHash_FuncDef PyHash_Func;
+#endif
+
+/* Count _Py_HashBytes() calls */
+#ifdef Py_HASH_STATS
+#define Py_HASH_STATS_MAX 32
+static Py_ssize_t hashstats[Py_HASH_STATS_MAX + 1] = {0};
+#endif
+
+/* For numeric types, the hash of a number x is based on the reduction
+ of x modulo the prime P = 2**_PyHASH_BITS - 1. It's designed so that
+ hash(x) == hash(y) whenever x and y are numerically equal, even if
+ x and y have different types.
+
+ A quick summary of the hashing strategy:
+
+ (1) First define the 'reduction of x modulo P' for any rational
+ number x; this is a standard extension of the usual notion of
+ reduction modulo P for integers. If x == p/q (written in lowest
+ terms), the reduction is interpreted as the reduction of p times
+ the inverse of the reduction of q, all modulo P; if q is exactly
+ divisible by P then define the reduction to be infinity. So we've
+ got a well-defined map
+
+ reduce : { rational numbers } -> { 0, 1, 2, ..., P-1, infinity }.
+
+ (2) Now for a rational number x, define hash(x) by:
+
+ reduce(x) if x >= 0
+ -reduce(-x) if x < 0
+
+ If the result of the reduction is infinity (this is impossible for
+ integers, floats and Decimals) then use the predefined hash value
+ _PyHASH_INF for x >= 0, or -_PyHASH_INF for x < 0, instead.
+ _PyHASH_INF, -_PyHASH_INF and _PyHASH_NAN are also used for the
+ hashes of float and Decimal infinities and nans.
+
+ A selling point for the above strategy is that it makes it possible
+ to compute hashes of decimal and binary floating-point numbers
+ efficiently, even if the exponent of the binary or decimal number
+ is large. The key point is that
+
+ reduce(x * y) == reduce(x) * reduce(y) (modulo _PyHASH_MODULUS)
+
+ provided that {reduce(x), reduce(y)} != {0, infinity}. The reduction of a
+ binary or decimal float is never infinity, since the denominator is a power
+ of 2 (for binary) or a divisor of a power of 10 (for decimal). So we have,
+ for nonnegative x,
+
+ reduce(x * 2**e) == reduce(x) * reduce(2**e) % _PyHASH_MODULUS
+
+ reduce(x * 10**e) == reduce(x) * reduce(10**e) % _PyHASH_MODULUS
+
+ and reduce(10**e) can be computed efficiently by the usual modular
+ exponentiation algorithm. For reduce(2**e) it's even better: since
+ P is of the form 2**n-1, reduce(2**e) is 2**(e mod n), and multiplication
+ by 2**(e mod n) modulo 2**n-1 just amounts to a rotation of bits.
+
+ */
+
+Py_hash_t
+_Py_HashDouble(double v)
+{
+ int e, sign;
+ double m;
+ Py_uhash_t x, y;
+
+ if (!Py_IS_FINITE(v)) {
+ if (Py_IS_INFINITY(v))
+ return v > 0 ? _PyHASH_INF : -_PyHASH_INF;
+ else
+ return _PyHASH_NAN;
+ }
+
+ m = frexp(v, &e);
+
+ sign = 1;
+ if (m < 0) {
+ sign = -1;
+ m = -m;
+ }
+
+ /* process 28 bits at a time; this should work well both for binary
+ and hexadecimal floating point. */
+ x = 0;
+ while (m) {
+ x = ((x << 28) & _PyHASH_MODULUS) | x >> (_PyHASH_BITS - 28);
+ m *= 268435456.0; /* 2**28 */
+ e -= 28;
+ y = (Py_uhash_t)m; /* pull out integer part */
+ m -= y;
+ x += y;
+ if (x >= _PyHASH_MODULUS)
+ x -= _PyHASH_MODULUS;
+ }
+
+ /* adjust for the exponent; first reduce it modulo _PyHASH_BITS */
+ e = e >= 0 ? e % _PyHASH_BITS : _PyHASH_BITS-1-((-1-e) % _PyHASH_BITS);
+ x = ((x << e) & _PyHASH_MODULUS) | x >> (_PyHASH_BITS - e);
+
+ x = x * sign;
+ if (x == (Py_uhash_t)-1)
+ x = (Py_uhash_t)-2;
+ return (Py_hash_t)x;
+}
+
+Py_hash_t
+_Py_HashPointerRaw(const void *p)
+{
+ size_t y = (size_t)p;
+ /* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid
+ excessive hash collisions for dicts and sets */
+ y = (y >> 4) | (y << (8 * SIZEOF_VOID_P - 4));
+ return (Py_hash_t)y;
+}
+
+Py_hash_t
+_Py_HashPointer(const void *p)
+{
+ Py_hash_t x = _Py_HashPointerRaw(p);
+ if (x == -1) {
+ x = -2;
+ }
+ return x;
+}
+
+Py_hash_t
+_Py_HashBytes(const void *src, Py_ssize_t len)
+{
+ Py_hash_t x;
+ /*
+ We make the hash of the empty string be 0, rather than using
+ (prefix ^ suffix), since this slightly obfuscates the hash secret
+ */
+ if (len == 0) {
+ return 0;
+ }
+
+#ifdef Py_HASH_STATS
+ hashstats[(len <= Py_HASH_STATS_MAX) ? len : 0]++;
+#endif
+
+#if Py_HASH_CUTOFF > 0
+ if (len < Py_HASH_CUTOFF) {
+ /* Optimize hashing of very small strings with inline DJBX33A. */
+ Py_uhash_t hash;
+ const unsigned char *p = src;
+ hash = 5381; /* DJBX33A starts with 5381 */
+
+ switch(len) {
+ /* ((hash << 5) + hash) + *p == hash * 33 + *p */
+ case 7: hash = ((hash << 5) + hash) + *p++; /* fallthrough */
+ case 6: hash = ((hash << 5) + hash) + *p++; /* fallthrough */
+ case 5: hash = ((hash << 5) + hash) + *p++; /* fallthrough */
+ case 4: hash = ((hash << 5) + hash) + *p++; /* fallthrough */
+ case 3: hash = ((hash << 5) + hash) + *p++; /* fallthrough */
+ case 2: hash = ((hash << 5) + hash) + *p++; /* fallthrough */
+ case 1: hash = ((hash << 5) + hash) + *p++; break;
+ default:
+ Py_UNREACHABLE();
+ }
+ hash ^= len;
+ hash ^= (Py_uhash_t) _Py_HashSecret.djbx33a.suffix;
+ x = (Py_hash_t)hash;
+ }
+ else
+#endif /* Py_HASH_CUTOFF */
+ x = PyHash_Func.hash(src, len);
+
+ if (x == -1)
+ return -2;
+ return x;
+}
+
+void
+_PyHash_Fini(void)
+{
+#ifdef Py_HASH_STATS
+ int i;
+ Py_ssize_t total = 0;
+ const char *fmt = "%2i %8" PY_FORMAT_SIZE_T "d %8" PY_FORMAT_SIZE_T "d\n";
+
+ fprintf(stderr, "len calls total\n");
+ for (i = 1; i <= Py_HASH_STATS_MAX; i++) {
+ total += hashstats[i];
+ fprintf(stderr, fmt, i, hashstats[i], total);
+ }
+ total += hashstats[0];
+ fprintf(stderr, "> %8" PY_FORMAT_SIZE_T "d %8" PY_FORMAT_SIZE_T "d\n",
+ hashstats[0], total);
+#endif
+}
+
+PyHash_FuncDef *
+PyHash_GetFuncDef(void)
+{
+ return &PyHash_Func;
+}
+
+/* Optimized memcpy() for Windows */
+#ifdef _MSC_VER
+# if SIZEOF_PY_UHASH_T == 4
+# define PY_UHASH_CPY(dst, src) do { \
+ dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; dst[3] = src[3]; \
+ } while(0)
+# elif SIZEOF_PY_UHASH_T == 8
+# define PY_UHASH_CPY(dst, src) do { \
+ dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; dst[3] = src[3]; \
+ dst[4] = src[4]; dst[5] = src[5]; dst[6] = src[6]; dst[7] = src[7]; \
+ } while(0)
+# else
+# error SIZEOF_PY_UHASH_T must be 4 or 8
+# endif /* SIZEOF_PY_UHASH_T */
+#else /* not Windows */
+# define PY_UHASH_CPY(dst, src) memcpy(dst, src, SIZEOF_PY_UHASH_T)
+#endif /* _MSC_VER */
+
+
+#if Py_HASH_ALGORITHM == Py_HASH_FNV
+/* **************************************************************************
+ * Modified Fowler-Noll-Vo (FNV) hash function
+ */
+static Py_hash_t
+fnv(const void *src, Py_ssize_t len)
+{
+ const unsigned char *p = src;
+ Py_uhash_t x;
+ Py_ssize_t remainder, blocks;
+ union {
+ Py_uhash_t value;
+ unsigned char bytes[SIZEOF_PY_UHASH_T];
+ } block;
+
+#ifdef Py_DEBUG
+ assert(_Py_HashSecret_Initialized);
+#endif
+ remainder = len % SIZEOF_PY_UHASH_T;
+ if (remainder == 0) {
+ /* Process at least one block byte by byte to reduce hash collisions
+ * for strings with common prefixes. */
+ remainder = SIZEOF_PY_UHASH_T;
+ }
+ blocks = (len - remainder) / SIZEOF_PY_UHASH_T;
+
+ x = (Py_uhash_t) _Py_HashSecret.fnv.prefix;
+ x ^= (Py_uhash_t) *p << 7;
+ while (blocks--) {
+ PY_UHASH_CPY(block.bytes, p);
+ x = (_PyHASH_MULTIPLIER * x) ^ block.value;
+ p += SIZEOF_PY_UHASH_T;
+ }
+ /* add remainder */
+ for (; remainder > 0; remainder--)
+ x = (_PyHASH_MULTIPLIER * x) ^ (Py_uhash_t) *p++;
+ x ^= (Py_uhash_t) len;
+ x ^= (Py_uhash_t) _Py_HashSecret.fnv.suffix;
+ if (x == (Py_uhash_t) -1) {
+ x = (Py_uhash_t) -2;
+ }
+ return x;
+}
+
+static PyHash_FuncDef PyHash_Func = {fnv, "fnv", 8 * SIZEOF_PY_HASH_T,
+ 16 * SIZEOF_PY_HASH_T};
+
+#endif /* Py_HASH_ALGORITHM == Py_HASH_FNV */
+
+
+/* **************************************************************************
+ <MIT License>
+ Copyright (c) 2013 Marek Majkowski <[email protected]>
+
+ 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.
+ </MIT License>
+
+ Original location:
+ https://github.com/majek/csiphash/
+
+ Solution inspired by code from:
+ Samuel Neves (supercop/crypto_auth/siphash24/little)
+ djb (supercop/crypto_auth/siphash24/little2)
+ Jean-Philippe Aumasson (https://131002.net/siphash/siphash24.c)
+
+ Modified for Python by Christian Heimes:
+ - C89 / MSVC compatibility
+ - _rotl64() on Windows
+ - letoh64() fallback
+*/
+
+/* byte swap little endian to host endian
+ * Endian conversion not only ensures that the hash function returns the same
+ * value on all platforms. It is also required to for a good dispersion of
+ * the hash values' least significant bits.
+ */
+#if PY_LITTLE_ENDIAN
+# define _le64toh(x) ((uint64_t)(x))
+#elif defined(__APPLE__)
+# define _le64toh(x) OSSwapLittleToHostInt64(x)
+#elif defined(HAVE_LETOH64)
+# define _le64toh(x) le64toh(x)
+#else
+# define _le64toh(x) (((uint64_t)(x) << 56) | \
+ (((uint64_t)(x) << 40) & 0xff000000000000ULL) | \
+ (((uint64_t)(x) << 24) & 0xff0000000000ULL) | \
+ (((uint64_t)(x) << 8) & 0xff00000000ULL) | \
+ (((uint64_t)(x) >> 8) & 0xff000000ULL) | \
+ (((uint64_t)(x) >> 24) & 0xff0000ULL) | \
+ (((uint64_t)(x) >> 40) & 0xff00ULL) | \
+ ((uint64_t)(x) >> 56))
+#endif
+
+
+#ifdef _MSC_VER
+# define ROTATE(x, b) _rotl64(x, b)
+#else
+# define ROTATE(x, b) (uint64_t)( ((x) << (b)) | ( (x) >> (64 - (b))) )
+#endif
+
+#define HALF_ROUND(a,b,c,d,s,t) \
+ a += b; c += d; \
+ b = ROTATE(b, s) ^ a; \
+ d = ROTATE(d, t) ^ c; \
+ a = ROTATE(a, 32);
+
+#define DOUBLE_ROUND(v0,v1,v2,v3) \
+ HALF_ROUND(v0,v1,v2,v3,13,16); \
+ HALF_ROUND(v2,v1,v0,v3,17,21); \
+ HALF_ROUND(v0,v1,v2,v3,13,16); \
+ HALF_ROUND(v2,v1,v0,v3,17,21);
+
+
+static uint64_t
+siphash24(uint64_t k0, uint64_t k1, const void *src, Py_ssize_t src_sz) {
+ uint64_t b = (uint64_t)src_sz << 56;
+ const uint8_t *in = (const uint8_t*)src;
+
+ uint64_t v0 = k0 ^ 0x736f6d6570736575ULL;
+ uint64_t v1 = k1 ^ 0x646f72616e646f6dULL;
+ uint64_t v2 = k0 ^ 0x6c7967656e657261ULL;
+ uint64_t v3 = k1 ^ 0x7465646279746573ULL;
+
+ uint64_t t;
+ uint8_t *pt;
+
+ while (src_sz >= 8) {
+ uint64_t mi;
+ memcpy(&mi, in, sizeof(mi));
+ mi = _le64toh(mi);
+ in += sizeof(mi);
+ src_sz -= sizeof(mi);
+ v3 ^= mi;
+ DOUBLE_ROUND(v0,v1,v2,v3);
+ v0 ^= mi;
+ }
+
+ t = 0;
+ pt = (uint8_t *)&t;
+ switch (src_sz) {
+ case 7: pt[6] = in[6]; /* fall through */
+ case 6: pt[5] = in[5]; /* fall through */
+ case 5: pt[4] = in[4]; /* fall through */
+ case 4: memcpy(pt, in, sizeof(uint32_t)); break;
+ case 3: pt[2] = in[2]; /* fall through */
+ case 2: pt[1] = in[1]; /* fall through */
+ case 1: pt[0] = in[0]; /* fall through */
+ }
+ b |= _le64toh(t);
+
+ v3 ^= b;
+ DOUBLE_ROUND(v0,v1,v2,v3);
+ v0 ^= b;
+ v2 ^= 0xff;
+ DOUBLE_ROUND(v0,v1,v2,v3);
+ DOUBLE_ROUND(v0,v1,v2,v3);
+
+ /* modified */
+ t = (v0 ^ v1) ^ (v2 ^ v3);
+ return t;
+}
+
+uint64_t
+_Py_KeyedHash(uint64_t key, const void *src, Py_ssize_t src_sz)
+{
+ return siphash24(key, 0, src, src_sz);
+}
+
+
+#if Py_HASH_ALGORITHM == Py_HASH_SIPHASH24
+static Py_hash_t
+pysiphash(const void *src, Py_ssize_t src_sz) {
+ return (Py_hash_t)siphash24(
+ _le64toh(_Py_HashSecret.siphash.k0), _le64toh(_Py_HashSecret.siphash.k1),
+ src, src_sz);
+}
+
+static PyHash_FuncDef PyHash_Func = {pysiphash, "siphash24", 64, 128};
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/contrib/tools/python3/src/Python/pylifecycle.c b/contrib/tools/python3/src/Python/pylifecycle.c
new file mode 100644
index 00000000000..7f591179ac4
--- /dev/null
+++ b/contrib/tools/python3/src/Python/pylifecycle.c
@@ -0,0 +1,2559 @@
+/* Python interpreter top-level routines, including init/exit */
+
+#include "Python.h"
+
+#include "Python-ast.h"
+#undef Yield /* undefine macro conflicting with <winbase.h> */
+
+#include "pycore_ceval.h" // _PyEval_FiniGIL()
+#include "pycore_context.h" // _PyContext_Init()
+#include "pycore_fileutils.h" // _Py_ResetForceASCII()
+#include "pycore_import.h" // _PyImport_Cleanup()
+#include "pycore_initconfig.h" // _PyStatus_OK()
+#include "pycore_object.h" // _PyDebug_PrintTotalRefs()
+#include "pycore_pathconfig.h" // _PyConfig_WritePathConfig()
+#include "pycore_pyerrors.h" // _PyErr_Occurred()
+#include "pycore_pylifecycle.h" // _PyErr_Print()
+#include "pycore_pystate.h" // _PyThreadState_GET()
+#include "pycore_sysmodule.h" // _PySys_ClearAuditHooks()
+#include "pycore_traceback.h" // _Py_DumpTracebackThreads()
+
+#include "grammar.h" // PyGrammar_RemoveAccelerators()
+#include <locale.h> // setlocale()
+
+#ifdef HAVE_SIGNAL_H
+# include <signal.h> // SIG_IGN
+#endif
+
+#ifdef HAVE_LANGINFO_H
+# include <langinfo.h> // nl_langinfo(CODESET)
+#endif
+
+#ifdef MS_WINDOWS
+# undef BYTE
+# include "windows.h"
+
+ extern PyTypeObject PyWindowsConsoleIO_Type;
+# define PyWindowsConsoleIO_Check(op) \
+ (PyObject_TypeCheck((op), &PyWindowsConsoleIO_Type))
+#endif
+
+
+_Py_IDENTIFIER(flush);
+_Py_IDENTIFIER(name);
+_Py_IDENTIFIER(stdin);
+_Py_IDENTIFIER(stdout);
+_Py_IDENTIFIER(stderr);
+_Py_IDENTIFIER(threading);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern grammar _PyParser_Grammar; /* From graminit.c */
+
+/* Forward declarations */
+static PyStatus add_main_module(PyInterpreterState *interp);
+static PyStatus init_import_site(void);
+static PyStatus init_set_builtins_open(void);
+static PyStatus init_sys_streams(PyThreadState *tstate);
+static void call_py_exitfuncs(PyThreadState *tstate);
+static void wait_for_thread_shutdown(PyThreadState *tstate);
+static void call_ll_exitfuncs(_PyRuntimeState *runtime);
+
+int _Py_UnhandledKeyboardInterrupt = 0;
+_PyRuntimeState _PyRuntime = _PyRuntimeState_INIT;
+static int runtime_initialized = 0;
+
+PyStatus
+_PyRuntime_Initialize(void)
+{
+ /* XXX We only initialize once in the process, which aligns with
+ the static initialization of the former globals now found in
+ _PyRuntime. However, _PyRuntime *should* be initialized with
+ every Py_Initialize() call, but doing so breaks the runtime.
+ This is because the runtime state is not properly finalized
+ currently. */
+ if (runtime_initialized) {
+ return _PyStatus_OK();
+ }
+ runtime_initialized = 1;
+
+ return _PyRuntimeState_Init(&_PyRuntime);
+}
+
+void
+_PyRuntime_Finalize(void)
+{
+ _PyRuntimeState_Fini(&_PyRuntime);
+ runtime_initialized = 0;
+}
+
+int
+_Py_IsFinalizing(void)
+{
+ return _PyRuntimeState_GetFinalizing(&_PyRuntime) != NULL;
+}
+
+/* Hack to force loading of object files */
+int (*_PyOS_mystrnicmp_hack)(const char *, const char *, Py_ssize_t) = \
+ PyOS_mystrnicmp; /* Python/pystrcmp.o */
+
+/* PyModule_GetWarningsModule is no longer necessary as of 2.6
+since _warnings is builtin. This API should not be used. */
+PyObject *
+PyModule_GetWarningsModule(void)
+{
+ return PyImport_ImportModule("warnings");
+}
+
+
+/* APIs to access the initialization flags
+ *
+ * Can be called prior to Py_Initialize.
+ */
+
+int
+_Py_IsCoreInitialized(void)
+{
+ return _PyRuntime.core_initialized;
+}
+
+int
+Py_IsInitialized(void)
+{
+ return _PyRuntime.initialized;
+}
+
+
+/* Global initializations. Can be undone by Py_FinalizeEx(). Don't
+ call this twice without an intervening Py_FinalizeEx() call. When
+ initializations fail, a fatal error is issued and the function does
+ not return. On return, the first thread and interpreter state have
+ been created.
+
+ Locking: you must hold the interpreter lock while calling this.
+ (If the lock has not yet been initialized, that's equivalent to
+ having the lock, but you cannot use multiple threads.)
+
+*/
+
+static PyStatus
+init_importlib(PyThreadState *tstate, PyObject *sysmod)
+{
+ PyObject *importlib;
+ PyObject *impmod;
+ PyObject *value;
+ PyInterpreterState *interp = tstate->interp;
+ int verbose = _PyInterpreterState_GetConfig(interp)->verbose;
+
+ /* Import _importlib through its frozen version, _frozen_importlib. */
+ if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) {
+ return _PyStatus_ERR("can't import _frozen_importlib");
+ }
+ else if (verbose) {
+ PySys_FormatStderr("import _frozen_importlib # frozen\n");
+ }
+ importlib = PyImport_AddModule("_frozen_importlib");
+ if (importlib == NULL) {
+ return _PyStatus_ERR("couldn't get _frozen_importlib from sys.modules");
+ }
+ interp->importlib = importlib;
+ Py_INCREF(interp->importlib);
+
+ interp->import_func = PyDict_GetItemString(interp->builtins, "__import__");
+ if (interp->import_func == NULL)
+ return _PyStatus_ERR("__import__ not found");
+ Py_INCREF(interp->import_func);
+
+ /* Import the _imp module */
+ impmod = PyInit__imp();
+ if (impmod == NULL) {
+ return _PyStatus_ERR("can't import _imp");
+ }
+ else if (verbose) {
+ PySys_FormatStderr("import _imp # builtin\n");
+ }
+ if (_PyImport_SetModuleString("_imp", impmod) < 0) {
+ return _PyStatus_ERR("can't save _imp to sys.modules");
+ }
+
+ /* Install importlib as the implementation of import */
+ value = PyObject_CallMethod(importlib, "_install", "OO", sysmod, impmod);
+ if (value == NULL) {
+ _PyErr_Print(tstate);
+ return _PyStatus_ERR("importlib install failed");
+ }
+ Py_DECREF(value);
+ Py_DECREF(impmod);
+
+ return _PyStatus_OK();
+}
+
+static PyStatus
+init_importlib_external(PyThreadState *tstate)
+{
+ PyObject *value;
+ value = PyObject_CallMethod(tstate->interp->importlib,
+ "_install_external_importers", "");
+ if (value == NULL) {
+ _PyErr_Print(tstate);
+ return _PyStatus_ERR("external importer setup failed");
+ }
+ Py_DECREF(value);
+
+ value = PyImport_ImportModule("__res");
+ if (value == NULL) {
+ PyErr_Print();
+ return _PyStatus_ERR("can't import __res");
+ }
+ Py_DECREF(value);
+
+ return _PyImportZip_Init(tstate);
+}
+
+/* Helper functions to better handle the legacy C locale
+ *
+ * The legacy C locale assumes ASCII as the default text encoding, which
+ * causes problems not only for the CPython runtime, but also other
+ * components like GNU readline.
+ *
+ * Accordingly, when the CLI detects it, it attempts to coerce it to a
+ * more capable UTF-8 based alternative as follows:
+ *
+ * if (_Py_LegacyLocaleDetected()) {
+ * _Py_CoerceLegacyLocale();
+ * }
+ *
+ * See the documentation of the PYTHONCOERCECLOCALE setting for more details.
+ *
+ * Locale coercion also impacts the default error handler for the standard
+ * streams: while the usual default is "strict", the default for the legacy
+ * C locale and for any of the coercion target locales is "surrogateescape".
+ */
+
+int
+_Py_LegacyLocaleDetected(int warn)
+{
+#ifndef MS_WINDOWS
+ if (!warn) {
+ const char *locale_override = getenv("LC_ALL");
+ if (locale_override != NULL && *locale_override != '\0') {
+ /* Don't coerce C locale if the LC_ALL environment variable
+ is set */
+ return 0;
+ }
+ }
+
+ /* On non-Windows systems, the C locale is considered a legacy locale */
+ /* XXX (ncoghlan): some platforms (notably Mac OS X) don't appear to treat
+ * the POSIX locale as a simple alias for the C locale, so
+ * we may also want to check for that explicitly.
+ */
+ const char *ctype_loc = setlocale(LC_CTYPE, NULL);
+ return ctype_loc != NULL && strcmp(ctype_loc, "C") == 0;
+#else
+ /* Windows uses code pages instead of locales, so no locale is legacy */
+ return 0;
+#endif
+}
+
+#ifndef MS_WINDOWS
+static const char *_C_LOCALE_WARNING =
+ "Python runtime initialized with LC_CTYPE=C (a locale with default ASCII "
+ "encoding), which may cause Unicode compatibility problems. Using C.UTF-8, "
+ "C.utf8, or UTF-8 (if available) as alternative Unicode-compatible "
+ "locales is recommended.\n";
+
+static void
+emit_stderr_warning_for_legacy_locale(_PyRuntimeState *runtime)
+{
+ const PyPreConfig *preconfig = &runtime->preconfig;
+ if (preconfig->coerce_c_locale_warn && _Py_LegacyLocaleDetected(1)) {
+ PySys_FormatStderr("%s", _C_LOCALE_WARNING);
+ }
+}
+#endif /* !defined(MS_WINDOWS) */
+
+typedef struct _CandidateLocale {
+ const char *locale_name; /* The locale to try as a coercion target */
+} _LocaleCoercionTarget;
+
+static _LocaleCoercionTarget _TARGET_LOCALES[] = {
+ {"C.UTF-8"},
+ {"C.utf8"},
+ {"UTF-8"},
+ {NULL}
+};
+
+
+int
+_Py_IsLocaleCoercionTarget(const char *ctype_loc)
+{
+ const _LocaleCoercionTarget *target = NULL;
+ for (target = _TARGET_LOCALES; target->locale_name; target++) {
+ if (strcmp(ctype_loc, target->locale_name) == 0) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+#ifdef PY_COERCE_C_LOCALE
+static const char C_LOCALE_COERCION_WARNING[] =
+ "Python detected LC_CTYPE=C: LC_CTYPE coerced to %.20s (set another locale "
+ "or PYTHONCOERCECLOCALE=0 to disable this locale coercion behavior).\n";
+
+static int
+_coerce_default_locale_settings(int warn, const _LocaleCoercionTarget *target)
+{
+ const char *newloc = target->locale_name;
+
+ /* Reset locale back to currently configured defaults */
+ _Py_SetLocaleFromEnv(LC_ALL);
+
+ /* Set the relevant locale environment variable */
+ if (setenv("LC_CTYPE", newloc, 1)) {
+ fprintf(stderr,
+ "Error setting LC_CTYPE, skipping C locale coercion\n");
+ return 0;
+ }
+ if (warn) {
+ fprintf(stderr, C_LOCALE_COERCION_WARNING, newloc);
+ }
+
+ /* Reconfigure with the overridden environment variables */
+ _Py_SetLocaleFromEnv(LC_ALL);
+ return 1;
+}
+#endif
+
+int
+_Py_CoerceLegacyLocale(int warn)
+{
+ int coerced = 0;
+#ifdef PY_COERCE_C_LOCALE
+ char *oldloc = NULL;
+
+ oldloc = _PyMem_RawStrdup(setlocale(LC_CTYPE, NULL));
+ if (oldloc == NULL) {
+ return coerced;
+ }
+
+ const char *locale_override = getenv("LC_ALL");
+ if (locale_override == NULL || *locale_override == '\0') {
+ /* LC_ALL is also not set (or is set to an empty string) */
+ const _LocaleCoercionTarget *target = NULL;
+ for (target = _TARGET_LOCALES; target->locale_name; target++) {
+ const char *new_locale = setlocale(LC_CTYPE,
+ target->locale_name);
+ if (new_locale != NULL) {
+#if !defined(_Py_FORCE_UTF8_LOCALE) && defined(HAVE_LANGINFO_H) && defined(CODESET)
+ /* Also ensure that nl_langinfo works in this locale */
+ char *codeset = nl_langinfo(CODESET);
+ if (!codeset || *codeset == '\0') {
+ /* CODESET is not set or empty, so skip coercion */
+ new_locale = NULL;
+ _Py_SetLocaleFromEnv(LC_CTYPE);
+ continue;
+ }
+#endif
+ /* Successfully configured locale, so make it the default */
+ coerced = _coerce_default_locale_settings(warn, target);
+ goto done;
+ }
+ }
+ }
+ /* No C locale warning here, as Py_Initialize will emit one later */
+
+ setlocale(LC_CTYPE, oldloc);
+
+done:
+ PyMem_RawFree(oldloc);
+#endif
+ return coerced;
+}
+
+/* _Py_SetLocaleFromEnv() is a wrapper around setlocale(category, "") to
+ * isolate the idiosyncrasies of different libc implementations. It reads the
+ * appropriate environment variable and uses its value to select the locale for
+ * 'category'. */
+char *
+_Py_SetLocaleFromEnv(int category)
+{
+ char *res;
+#ifdef __ANDROID__
+ const char *locale;
+ const char **pvar;
+#ifdef PY_COERCE_C_LOCALE
+ const char *coerce_c_locale;
+#endif
+ const char *utf8_locale = "C.UTF-8";
+ const char *env_var_set[] = {
+ "LC_ALL",
+ "LC_CTYPE",
+ "LANG",
+ NULL,
+ };
+
+ /* Android setlocale(category, "") doesn't check the environment variables
+ * and incorrectly sets the "C" locale at API 24 and older APIs. We only
+ * check the environment variables listed in env_var_set. */
+ for (pvar=env_var_set; *pvar; pvar++) {
+ locale = getenv(*pvar);
+ if (locale != NULL && *locale != '\0') {
+ if (strcmp(locale, utf8_locale) == 0 ||
+ strcmp(locale, "en_US.UTF-8") == 0) {
+ return setlocale(category, utf8_locale);
+ }
+ return setlocale(category, "C");
+ }
+ }
+
+ /* Android uses UTF-8, so explicitly set the locale to C.UTF-8 if none of
+ * LC_ALL, LC_CTYPE, or LANG is set to a non-empty string.
+ * Quote from POSIX section "8.2 Internationalization Variables":
+ * "4. If the LANG environment variable is not set or is set to the empty
+ * string, the implementation-defined default locale shall be used." */
+
+#ifdef PY_COERCE_C_LOCALE
+ coerce_c_locale = getenv("PYTHONCOERCECLOCALE");
+ if (coerce_c_locale == NULL || strcmp(coerce_c_locale, "0") != 0) {
+ /* Some other ported code may check the environment variables (e.g. in
+ * extension modules), so we make sure that they match the locale
+ * configuration */
+ if (setenv("LC_CTYPE", utf8_locale, 1)) {
+ fprintf(stderr, "Warning: failed setting the LC_CTYPE "
+ "environment variable to %s\n", utf8_locale);
+ }
+ }
+#endif
+ res = setlocale(category, utf8_locale);
+#else /* !defined(__ANDROID__) */
+ res = setlocale(category, "");
+#endif
+ _Py_ResetForceASCII();
+ return res;
+}
+
+
+/* Global initializations. Can be undone by Py_Finalize(). Don't
+ call this twice without an intervening Py_Finalize() call.
+
+ Every call to Py_InitializeFromConfig, Py_Initialize or Py_InitializeEx
+ must have a corresponding call to Py_Finalize.
+
+ Locking: you must hold the interpreter lock while calling these APIs.
+ (If the lock has not yet been initialized, that's equivalent to
+ having the lock, but you cannot use multiple threads.)
+
+*/
+
+static PyStatus
+pyinit_core_reconfigure(_PyRuntimeState *runtime,
+ PyThreadState **tstate_p,
+ const PyConfig *config)
+{
+ PyStatus status;
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (!tstate) {
+ return _PyStatus_ERR("failed to read thread state");
+ }
+ *tstate_p = tstate;
+
+ PyInterpreterState *interp = tstate->interp;
+ if (interp == NULL) {
+ return _PyStatus_ERR("can't make main interpreter");
+ }
+
+ status = _PyConfig_Write(config, runtime);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ status = _PyInterpreterState_SetConfig(interp, config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ config = _PyInterpreterState_GetConfig(interp);
+
+ if (config->_install_importlib) {
+ status = _PyConfig_WritePathConfig(config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+ return _PyStatus_OK();
+}
+
+
+static PyStatus
+pycore_init_runtime(_PyRuntimeState *runtime,
+ const PyConfig *config)
+{
+ if (runtime->initialized) {
+ return _PyStatus_ERR("main interpreter already initialized");
+ }
+
+ PyStatus status = _PyConfig_Write(config, runtime);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ /* Py_Finalize leaves _Py_Finalizing set in order to help daemon
+ * threads behave a little more gracefully at interpreter shutdown.
+ * We clobber it here so the new interpreter can start with a clean
+ * slate.
+ *
+ * However, this may still lead to misbehaviour if there are daemon
+ * threads still hanging around from a previous Py_Initialize/Finalize
+ * pair :(
+ */
+ _PyRuntimeState_SetFinalizing(runtime, NULL);
+
+ status = _Py_HashRandomization_Init(config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ status = _PyInterpreterState_Enable(runtime);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ return _PyStatus_OK();
+}
+
+
+static PyStatus
+init_interp_create_gil(PyThreadState *tstate)
+{
+ PyStatus status;
+
+ /* finalize_interp_delete() comment explains why _PyEval_FiniGIL() is
+ only called here. */
+ _PyEval_FiniGIL(tstate);
+
+ /* Auto-thread-state API */
+ status = _PyGILState_Init(tstate);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ /* Create the GIL and take it */
+ status = _PyEval_InitGIL(tstate);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ return _PyStatus_OK();
+}
+
+
+static PyStatus
+pycore_create_interpreter(_PyRuntimeState *runtime,
+ const PyConfig *config,
+ PyThreadState **tstate_p)
+{
+ PyInterpreterState *interp = PyInterpreterState_New();
+ if (interp == NULL) {
+ return _PyStatus_ERR("can't make main interpreter");
+ }
+
+ PyStatus status = _PyInterpreterState_SetConfig(interp, config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ PyThreadState *tstate = PyThreadState_New(interp);
+ if (tstate == NULL) {
+ return _PyStatus_ERR("can't make first thread");
+ }
+ (void) PyThreadState_Swap(tstate);
+
+ status = init_interp_create_gil(tstate);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ *tstate_p = tstate;
+ return _PyStatus_OK();
+}
+
+
+static PyStatus
+pycore_init_types(PyThreadState *tstate)
+{
+ PyStatus status;
+ int is_main_interp = _Py_IsMainInterpreter(tstate);
+
+ status = _PyGC_Init(tstate);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ if (is_main_interp) {
+ status = _PyTypes_Init();
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+
+ if (!_PyLong_Init(tstate)) {
+ return _PyStatus_ERR("can't init longs");
+ }
+
+ if (is_main_interp) {
+ status = _PyUnicode_Init();
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ status = _PyExc_Init();
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ if (is_main_interp) {
+ if (!_PyFloat_Init()) {
+ return _PyStatus_ERR("can't init float");
+ }
+
+ if (_PyStructSequence_Init() < 0) {
+ return _PyStatus_ERR("can't initialize structseq");
+ }
+ }
+
+ status = _PyErr_Init();
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ if (is_main_interp) {
+ if (!_PyContext_Init()) {
+ return _PyStatus_ERR("can't init context");
+ }
+ }
+
+ return _PyStatus_OK();
+}
+
+
+static PyStatus
+pycore_init_builtins(PyThreadState *tstate)
+{
+ assert(!_PyErr_Occurred(tstate));
+
+ PyObject *bimod = _PyBuiltin_Init(tstate);
+ if (bimod == NULL) {
+ goto error;
+ }
+
+ PyInterpreterState *interp = tstate->interp;
+ if (_PyImport_FixupBuiltin(bimod, "builtins", interp->modules) < 0) {
+ goto error;
+ }
+
+ PyObject *builtins_dict = PyModule_GetDict(bimod);
+ if (builtins_dict == NULL) {
+ goto error;
+ }
+ Py_INCREF(builtins_dict);
+ interp->builtins = builtins_dict;
+
+ PyStatus status = _PyBuiltins_AddExceptions(bimod);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ interp->builtins_copy = PyDict_Copy(interp->builtins);
+ if (interp->builtins_copy == NULL) {
+ goto error;
+ }
+ Py_DECREF(bimod);
+
+ assert(!_PyErr_Occurred(tstate));
+
+ return _PyStatus_OK();
+
+error:
+ Py_XDECREF(bimod);
+ return _PyStatus_ERR("can't initialize builtins module");
+}
+
+
+static PyStatus
+pycore_init_import_warnings(PyThreadState *tstate, PyObject *sysmod)
+{
+ assert(!_PyErr_Occurred(tstate));
+
+ PyStatus status = _PyImportHooks_Init(tstate);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
+ if (_Py_IsMainInterpreter(tstate)) {
+ /* Initialize _warnings. */
+ status = _PyWarnings_InitState(tstate);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ if (config->_install_importlib) {
+ status = _PyConfig_WritePathConfig(config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+ }
+
+ /* This call sets up builtin and frozen import support */
+ if (config->_install_importlib) {
+ status = init_importlib(tstate, sysmod);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ assert(!_PyErr_Occurred(tstate));
+
+ return _PyStatus_OK();
+}
+
+
+static PyStatus
+pycore_interp_init(PyThreadState *tstate)
+{
+ PyStatus status;
+ PyObject *sysmod = NULL;
+
+ status = pycore_init_types(tstate);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+
+ status = _PySys_Create(tstate, &sysmod);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+
+ status = pycore_init_builtins(tstate);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+
+ status = pycore_init_import_warnings(tstate, sysmod);
+
+done:
+ /* sys.modules['sys'] contains a strong reference to the module */
+ Py_XDECREF(sysmod);
+ return status;
+}
+
+
+static PyStatus
+pyinit_config(_PyRuntimeState *runtime,
+ PyThreadState **tstate_p,
+ const PyConfig *config)
+{
+ PyStatus status = pycore_init_runtime(runtime, config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ PyThreadState *tstate;
+ status = pycore_create_interpreter(runtime, config, &tstate);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ *tstate_p = tstate;
+
+ status = pycore_interp_init(tstate);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ /* Only when we get here is the runtime core fully initialized */
+ runtime->core_initialized = 1;
+ return _PyStatus_OK();
+}
+
+
+PyStatus
+_Py_PreInitializeFromPyArgv(const PyPreConfig *src_config, const _PyArgv *args)
+{
+ PyStatus status;
+
+ if (src_config == NULL) {
+ return _PyStatus_ERR("preinitialization config is NULL");
+ }
+
+ status = _PyRuntime_Initialize();
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ _PyRuntimeState *runtime = &_PyRuntime;
+
+ if (runtime->preinitialized) {
+ /* If it's already configured: ignored the new configuration */
+ return _PyStatus_OK();
+ }
+
+ /* Note: preinitialized remains 1 on error, it is only set to 0
+ at exit on success. */
+ runtime->preinitializing = 1;
+
+ PyPreConfig config;
+
+ status = _PyPreConfig_InitFromPreConfig(&config, src_config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ status = _PyPreConfig_Read(&config, args);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ status = _PyPreConfig_Write(&config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ runtime->preinitializing = 0;
+ runtime->preinitialized = 1;
+ return _PyStatus_OK();
+}
+
+
+PyStatus
+Py_PreInitializeFromBytesArgs(const PyPreConfig *src_config, Py_ssize_t argc, char **argv)
+{
+ _PyArgv args = {.use_bytes_argv = 1, .argc = argc, .bytes_argv = argv};
+ return _Py_PreInitializeFromPyArgv(src_config, &args);
+}
+
+
+PyStatus
+Py_PreInitializeFromArgs(const PyPreConfig *src_config, Py_ssize_t argc, wchar_t **argv)
+{
+ _PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv};
+ return _Py_PreInitializeFromPyArgv(src_config, &args);
+}
+
+
+PyStatus
+Py_PreInitialize(const PyPreConfig *src_config)
+{
+ return _Py_PreInitializeFromPyArgv(src_config, NULL);
+}
+
+
+PyStatus
+_Py_PreInitializeFromConfig(const PyConfig *config,
+ const _PyArgv *args)
+{
+ assert(config != NULL);
+
+ PyStatus status = _PyRuntime_Initialize();
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ _PyRuntimeState *runtime = &_PyRuntime;
+
+ if (runtime->preinitialized) {
+ /* Already initialized: do nothing */
+ return _PyStatus_OK();
+ }
+
+ PyPreConfig preconfig;
+
+ _PyPreConfig_InitFromConfig(&preconfig, config);
+
+ if (!config->parse_argv) {
+ return Py_PreInitialize(&preconfig);
+ }
+ else if (args == NULL) {
+ _PyArgv config_args = {
+ .use_bytes_argv = 0,
+ .argc = config->argv.length,
+ .wchar_argv = config->argv.items};
+ return _Py_PreInitializeFromPyArgv(&preconfig, &config_args);
+ }
+ else {
+ return _Py_PreInitializeFromPyArgv(&preconfig, args);
+ }
+}
+
+
+/* Begin interpreter initialization
+ *
+ * On return, the first thread and interpreter state have been created,
+ * but the compiler, signal handling, multithreading and
+ * multiple interpreter support, and codec infrastructure are not yet
+ * available.
+ *
+ * The import system will support builtin and frozen modules only.
+ * The only supported io is writing to sys.stderr
+ *
+ * If any operation invoked by this function fails, a fatal error is
+ * issued and the function does not return.
+ *
+ * Any code invoked from this function should *not* assume it has access
+ * to the Python C API (unless the API is explicitly listed as being
+ * safe to call without calling Py_Initialize first)
+ */
+static PyStatus
+pyinit_core(_PyRuntimeState *runtime,
+ const PyConfig *src_config,
+ PyThreadState **tstate_p)
+{
+ PyStatus status;
+
+ status = _Py_PreInitializeFromConfig(src_config, NULL);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ PyConfig config;
+ _PyConfig_InitCompatConfig(&config);
+
+ status = _PyConfig_Copy(&config, src_config);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+
+ status = PyConfig_Read(&config);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+
+ if (!runtime->core_initialized) {
+ status = pyinit_config(runtime, tstate_p, &config);
+ }
+ else {
+ status = pyinit_core_reconfigure(runtime, tstate_p, &config);
+ }
+ if (_PyStatus_EXCEPTION(status)) {
+ goto done;
+ }
+
+done:
+ PyConfig_Clear(&config);
+ return status;
+}
+
+
+/* Py_Initialize() has already been called: update the main interpreter
+ configuration. Example of bpo-34008: Py_Main() called after
+ Py_Initialize(). */
+static PyStatus
+_Py_ReconfigureMainInterpreter(PyThreadState *tstate)
+{
+ const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
+
+ PyObject *argv = _PyWideStringList_AsList(&config->argv);
+ if (argv == NULL) {
+ return _PyStatus_NO_MEMORY(); \
+ }
+
+ int res = PyDict_SetItemString(tstate->interp->sysdict, "argv", argv);
+ Py_DECREF(argv);
+ if (res < 0) {
+ return _PyStatus_ERR("fail to set sys.argv");
+ }
+ return _PyStatus_OK();
+}
+
+
+static PyStatus
+init_interp_main(PyThreadState *tstate)
+{
+ assert(!_PyErr_Occurred(tstate));
+
+ PyStatus status;
+ int is_main_interp = _Py_IsMainInterpreter(tstate);
+ PyInterpreterState *interp = tstate->interp;
+ const PyConfig *config = _PyInterpreterState_GetConfig(interp);
+
+ if (!config->_install_importlib) {
+ /* Special mode for freeze_importlib: run with no import system
+ *
+ * This means anything which needs support from extension modules
+ * or pure Python code in the standard library won't work.
+ */
+ if (is_main_interp) {
+ interp->runtime->initialized = 1;
+ }
+ return _PyStatus_OK();
+ }
+
+ if (is_main_interp) {
+ if (_PyTime_Init() < 0) {
+ return _PyStatus_ERR("can't initialize time");
+ }
+ }
+
+ if (_PySys_InitMain(tstate) < 0) {
+ return _PyStatus_ERR("can't finish initializing sys");
+ }
+
+ status = init_importlib_external(tstate);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ if (is_main_interp) {
+ /* initialize the faulthandler module */
+ status = _PyFaulthandler_Init(config->faulthandler);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ status = _PyUnicode_InitEncodings(tstate);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ if (is_main_interp) {
+ if (_PySignal_Init(config->install_signal_handlers) < 0) {
+ return _PyStatus_ERR("can't initialize signals");
+ }
+
+ if (_PyTraceMalloc_Init(config->tracemalloc) < 0) {
+ return _PyStatus_ERR("can't initialize tracemalloc");
+ }
+ }
+
+ status = init_sys_streams(tstate);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ status = init_set_builtins_open();
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ status = add_main_module(interp);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ if (is_main_interp) {
+ /* Initialize warnings. */
+ PyObject *warnoptions = PySys_GetObject("warnoptions");
+ if (warnoptions != NULL && PyList_Size(warnoptions) > 0)
+ {
+ PyObject *warnings_module = PyImport_ImportModule("warnings");
+ if (warnings_module == NULL) {
+ fprintf(stderr, "'import warnings' failed; traceback:\n");
+ _PyErr_Print(tstate);
+ }
+ Py_XDECREF(warnings_module);
+ }
+
+ interp->runtime->initialized = 1;
+ }
+
+ if (config->site_import) {
+ status = init_import_site();
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ if (is_main_interp) {
+#ifndef MS_WINDOWS
+ emit_stderr_warning_for_legacy_locale(interp->runtime);
+#endif
+ }
+
+ assert(!_PyErr_Occurred(tstate));
+
+ return _PyStatus_OK();
+}
+
+
+/* Update interpreter state based on supplied configuration settings
+ *
+ * After calling this function, most of the restrictions on the interpreter
+ * are lifted. The only remaining incomplete settings are those related
+ * to the main module (sys.argv[0], __main__ metadata)
+ *
+ * Calling this when the interpreter is not initializing, is already
+ * initialized or without a valid current thread state is a fatal error.
+ * Other errors should be reported as normal Python exceptions with a
+ * non-zero return code.
+ */
+static PyStatus
+pyinit_main(PyThreadState *tstate)
+{
+ PyInterpreterState *interp = tstate->interp;
+ if (!interp->runtime->core_initialized) {
+ return _PyStatus_ERR("runtime core not initialized");
+ }
+
+ if (interp->runtime->initialized) {
+ return _Py_ReconfigureMainInterpreter(tstate);
+ }
+
+ PyStatus status = init_interp_main(tstate);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ return _PyStatus_OK();
+}
+
+
+PyStatus
+_Py_InitializeMain(void)
+{
+ PyStatus status = _PyRuntime_Initialize();
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ _PyRuntimeState *runtime = &_PyRuntime;
+ PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
+ return pyinit_main(tstate);
+}
+
+
+PyStatus
+Py_InitializeFromConfig(const PyConfig *config)
+{
+ if (config == NULL) {
+ return _PyStatus_ERR("initialization config is NULL");
+ }
+
+ PyStatus status;
+
+ status = _PyRuntime_Initialize();
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ _PyRuntimeState *runtime = &_PyRuntime;
+
+ PyThreadState *tstate = NULL;
+ status = pyinit_core(runtime, config, &tstate);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ config = _PyInterpreterState_GetConfig(tstate->interp);
+
+ if (config->_init_main) {
+ status = pyinit_main(tstate);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ return _PyStatus_OK();
+}
+
+
+void
+Py_InitializeEx(int install_sigs)
+{
+ PyStatus status;
+
+ status = _PyRuntime_Initialize();
+ if (_PyStatus_EXCEPTION(status)) {
+ Py_ExitStatusException(status);
+ }
+ _PyRuntimeState *runtime = &_PyRuntime;
+
+ if (runtime->initialized) {
+ /* bpo-33932: Calling Py_Initialize() twice does nothing. */
+ return;
+ }
+
+ PyConfig config;
+ _PyConfig_InitCompatConfig(&config);
+
+ config.install_signal_handlers = install_sigs;
+
+ status = Py_InitializeFromConfig(&config);
+ if (_PyStatus_EXCEPTION(status)) {
+ Py_ExitStatusException(status);
+ }
+}
+
+void
+Py_Initialize(void)
+{
+ Py_InitializeEx(1);
+}
+
+
+/* Flush stdout and stderr */
+
+static int
+file_is_closed(PyObject *fobj)
+{
+ int r;
+ PyObject *tmp = PyObject_GetAttrString(fobj, "closed");
+ if (tmp == NULL) {
+ PyErr_Clear();
+ return 0;
+ }
+ r = PyObject_IsTrue(tmp);
+ Py_DECREF(tmp);
+ if (r < 0)
+ PyErr_Clear();
+ return r > 0;
+}
+
+static int
+flush_std_files(void)
+{
+ PyObject *fout = _PySys_GetObjectId(&PyId_stdout);
+ PyObject *ferr = _PySys_GetObjectId(&PyId_stderr);
+ PyObject *tmp;
+ int status = 0;
+
+ if (fout != NULL && fout != Py_None && !file_is_closed(fout)) {
+ tmp = _PyObject_CallMethodIdNoArgs(fout, &PyId_flush);
+ if (tmp == NULL) {
+ PyErr_WriteUnraisable(fout);
+ status = -1;
+ }
+ else
+ Py_DECREF(tmp);
+ }
+
+ if (ferr != NULL && ferr != Py_None && !file_is_closed(ferr)) {
+ tmp = _PyObject_CallMethodIdNoArgs(ferr, &PyId_flush);
+ if (tmp == NULL) {
+ PyErr_Clear();
+ status = -1;
+ }
+ else
+ Py_DECREF(tmp);
+ }
+
+ return status;
+}
+
+/* Undo the effect of Py_Initialize().
+
+ Beware: if multiple interpreter and/or thread states exist, these
+ are not wiped out; only the current thread and interpreter state
+ are deleted. But since everything else is deleted, those other
+ interpreter and thread states should no longer be used.
+
+ (XXX We should do better, e.g. wipe out all interpreters and
+ threads.)
+
+ Locking: as above.
+
+*/
+
+
+static void
+finalize_interp_types(PyThreadState *tstate, int is_main_interp)
+{
+ if (is_main_interp) {
+ /* Sundry finalizers */
+ _PyAST_Fini();
+ _PyFrame_Fini();
+ _PyTuple_Fini();
+ _PyList_Fini();
+ _PySet_Fini();
+ _PyBytes_Fini();
+ }
+
+ _PyLong_Fini(tstate);
+
+ if (is_main_interp) {
+ _PyFloat_Fini();
+ _PyDict_Fini();
+ _PySlice_Fini();
+ }
+
+ _PyWarnings_Fini(tstate->interp);
+
+ if (is_main_interp) {
+ _Py_HashRandomization_Fini();
+ _PyArg_Fini();
+ _PyAsyncGen_Fini();
+ _PyContext_Fini();
+ }
+
+ /* Cleanup Unicode implementation */
+ _PyUnicode_Fini(tstate);
+
+ if (is_main_interp) {
+ _Py_ClearFileSystemEncoding();
+ }
+}
+
+
+static void
+finalize_interp_clear(PyThreadState *tstate)
+{
+ int is_main_interp = _Py_IsMainInterpreter(tstate);
+
+ /* Clear interpreter state and all thread states */
+ PyInterpreterState_Clear(tstate->interp);
+
+ /* Trigger a GC collection on subinterpreters*/
+ if (!is_main_interp) {
+ _PyGC_CollectNoFail();
+ }
+
+ /* Clear all loghooks */
+ /* Both _PySys_Audit function and users still need PyObject, such as tuple.
+ Call _PySys_ClearAuditHooks when PyObject available. */
+ if (is_main_interp) {
+ _PySys_ClearAuditHooks(tstate);
+ }
+
+ finalize_interp_types(tstate, is_main_interp);
+
+ if (is_main_interp) {
+ /* XXX Still allocated:
+ - various static ad-hoc pointers to interned strings
+ - int and float free list blocks
+ - whatever various modules and libraries allocate
+ */
+
+ PyGrammar_RemoveAccelerators(&_PyParser_Grammar);
+
+ _PyExc_Fini();
+ }
+
+ _PyGC_Fini(tstate);
+}
+
+
+static void
+finalize_interp_delete(PyThreadState *tstate)
+{
+ if (_Py_IsMainInterpreter(tstate)) {
+ /* Cleanup auto-thread-state */
+ _PyGILState_Fini(tstate);
+ }
+
+ /* We can't call _PyEval_FiniGIL() here because destroying the GIL lock can
+ fail when it is being awaited by another running daemon thread (see
+ bpo-9901). Instead pycore_create_interpreter() destroys the previously
+ created GIL, which ensures that Py_Initialize / Py_FinalizeEx can be
+ called multiple times. */
+
+ PyInterpreterState_Delete(tstate->interp);
+}
+
+
+int
+Py_FinalizeEx(void)
+{
+ int status = 0;
+
+ _PyRuntimeState *runtime = &_PyRuntime;
+ if (!runtime->initialized) {
+ return status;
+ }
+
+ /* Get current thread state and interpreter pointer */
+ PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
+
+ // Wrap up existing "threading"-module-created, non-daemon threads.
+ wait_for_thread_shutdown(tstate);
+
+ // Make any remaining pending calls.
+ _Py_FinishPendingCalls(tstate);
+
+ /* The interpreter is still entirely intact at this point, and the
+ * exit funcs may be relying on that. In particular, if some thread
+ * or exit func is still waiting to do an import, the import machinery
+ * expects Py_IsInitialized() to return true. So don't say the
+ * runtime is uninitialized until after the exit funcs have run.
+ * Note that Threading.py uses an exit func to do a join on all the
+ * threads created thru it, so this also protects pending imports in
+ * the threads created via Threading.
+ */
+
+ call_py_exitfuncs(tstate);
+
+ /* Copy the core config, PyInterpreterState_Delete() free
+ the core config memory */
+#ifdef Py_REF_DEBUG
+ int show_ref_count = tstate->interp->config.show_ref_count;
+#endif
+#ifdef Py_TRACE_REFS
+ int dump_refs = tstate->interp->config.dump_refs;
+#endif
+#ifdef WITH_PYMALLOC
+ int malloc_stats = tstate->interp->config.malloc_stats;
+#endif
+
+ /* Remaining daemon threads will automatically exit
+ when they attempt to take the GIL (ex: PyEval_RestoreThread()). */
+ _PyRuntimeState_SetFinalizing(runtime, tstate);
+ runtime->initialized = 0;
+ runtime->core_initialized = 0;
+
+ /* Destroy the state of all threads of the interpreter, except of the
+ current thread. In practice, only daemon threads should still be alive,
+ except if wait_for_thread_shutdown() has been cancelled by CTRL+C.
+ Clear frames of other threads to call objects destructors. Destructors
+ will be called in the current Python thread. Since
+ _PyRuntimeState_SetFinalizing() has been called, no other Python thread
+ can take the GIL at this point: if they try, they will exit
+ immediately. */
+ _PyThreadState_DeleteExcept(runtime, tstate);
+
+ /* Flush sys.stdout and sys.stderr */
+ if (flush_std_files() < 0) {
+ status = -1;
+ }
+
+ /* Disable signal handling */
+ PyOS_FiniInterrupts();
+
+ /* Collect garbage. This may call finalizers; it's nice to call these
+ * before all modules are destroyed.
+ * XXX If a __del__ or weakref callback is triggered here, and tries to
+ * XXX import a module, bad things can happen, because Python no
+ * XXX longer believes it's initialized.
+ * XXX Fatal Python error: Interpreter not initialized (version mismatch?)
+ * XXX is easy to provoke that way. I've also seen, e.g.,
+ * XXX Exception exceptions.ImportError: 'No module named sha'
+ * XXX in <function callback at 0x008F5718> ignored
+ * XXX but I'm unclear on exactly how that one happens. In any case,
+ * XXX I haven't seen a real-life report of either of these.
+ */
+ _PyGC_CollectIfEnabled();
+
+ /* Destroy all modules */
+ _PyImport_Cleanup(tstate);
+
+ /* Print debug stats if any */
+ _PyEval_Fini();
+
+ /* Flush sys.stdout and sys.stderr (again, in case more was printed) */
+ if (flush_std_files() < 0) {
+ status = -1;
+ }
+
+ /* Collect final garbage. This disposes of cycles created by
+ * class definitions, for example.
+ * XXX This is disabled because it caused too many problems. If
+ * XXX a __del__ or weakref callback triggers here, Python code has
+ * XXX a hard time running, because even the sys module has been
+ * XXX cleared out (sys.stdout is gone, sys.excepthook is gone, etc).
+ * XXX One symptom is a sequence of information-free messages
+ * XXX coming from threads (if a __del__ or callback is invoked,
+ * XXX other threads can execute too, and any exception they encounter
+ * XXX triggers a comedy of errors as subsystem after subsystem
+ * XXX fails to find what it *expects* to find in sys to help report
+ * XXX the exception and consequent unexpected failures). I've also
+ * XXX seen segfaults then, after adding print statements to the
+ * XXX Python code getting called.
+ */
+#if 0
+ _PyGC_CollectIfEnabled();
+#endif
+
+ /* Disable tracemalloc after all Python objects have been destroyed,
+ so it is possible to use tracemalloc in objects destructor. */
+ _PyTraceMalloc_Fini();
+
+ /* Destroy the database used by _PyImport_{Fixup,Find}Extension */
+ _PyImport_Fini();
+
+ /* Cleanup typeobject.c's internal caches. */
+ _PyType_Fini();
+
+ /* unload faulthandler module */
+ _PyFaulthandler_Fini();
+
+ /* dump hash stats */
+ _PyHash_Fini();
+
+#ifdef Py_REF_DEBUG
+ if (show_ref_count) {
+ _PyDebug_PrintTotalRefs();
+ }
+#endif
+
+#ifdef Py_TRACE_REFS
+ /* Display all objects still alive -- this can invoke arbitrary
+ * __repr__ overrides, so requires a mostly-intact interpreter.
+ * Alas, a lot of stuff may still be alive now that will be cleaned
+ * up later.
+ */
+ if (dump_refs) {
+ _Py_PrintReferences(stderr);
+ }
+#endif /* Py_TRACE_REFS */
+
+ finalize_interp_clear(tstate);
+ finalize_interp_delete(tstate);
+
+#ifdef Py_TRACE_REFS
+ /* Display addresses (& refcnts) of all objects still alive.
+ * An address can be used to find the repr of the object, printed
+ * above by _Py_PrintReferences.
+ */
+ if (dump_refs) {
+ _Py_PrintReferenceAddresses(stderr);
+ }
+#endif /* Py_TRACE_REFS */
+#ifdef WITH_PYMALLOC
+ if (malloc_stats) {
+ _PyObject_DebugMallocStats(stderr);
+ }
+#endif
+
+ call_ll_exitfuncs(runtime);
+
+ _PyRuntime_Finalize();
+ return status;
+}
+
+void
+Py_Finalize(void)
+{
+ Py_FinalizeEx();
+}
+
+
+/* Create and initialize a new interpreter and thread, and return the
+ new thread. This requires that Py_Initialize() has been called
+ first.
+
+ Unsuccessful initialization yields a NULL pointer. Note that *no*
+ exception information is available even in this case -- the
+ exception information is held in the thread, and there is no
+ thread.
+
+ Locking: as above.
+
+*/
+
+static PyStatus
+new_interpreter(PyThreadState **tstate_p, int isolated_subinterpreter)
+{
+ PyStatus status;
+
+ status = _PyRuntime_Initialize();
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ _PyRuntimeState *runtime = &_PyRuntime;
+
+ if (!runtime->initialized) {
+ return _PyStatus_ERR("Py_Initialize must be called first");
+ }
+
+ /* Issue #10915, #15751: The GIL API doesn't work with multiple
+ interpreters: disable PyGILState_Check(). */
+ runtime->gilstate.check_enabled = 0;
+
+ PyInterpreterState *interp = PyInterpreterState_New();
+ if (interp == NULL) {
+ *tstate_p = NULL;
+ return _PyStatus_OK();
+ }
+
+ PyThreadState *tstate = PyThreadState_New(interp);
+ if (tstate == NULL) {
+ PyInterpreterState_Delete(interp);
+ *tstate_p = NULL;
+ return _PyStatus_OK();
+ }
+
+ PyThreadState *save_tstate = PyThreadState_Swap(tstate);
+
+ /* Copy the current interpreter config into the new interpreter */
+ const PyConfig *config;
+ if (save_tstate != NULL) {
+ config = _PyInterpreterState_GetConfig(save_tstate->interp);
+ }
+ else
+ {
+ /* No current thread state, copy from the main interpreter */
+ PyInterpreterState *main_interp = PyInterpreterState_Main();
+ config = _PyInterpreterState_GetConfig(main_interp);
+ }
+
+ status = _PyInterpreterState_SetConfig(interp, config);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto error;
+ }
+ interp->config._isolated_interpreter = isolated_subinterpreter;
+
+ status = init_interp_create_gil(tstate);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto error;
+ }
+
+ status = pycore_interp_init(tstate);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto error;
+ }
+
+ status = init_interp_main(tstate);
+ if (_PyStatus_EXCEPTION(status)) {
+ goto error;
+ }
+
+ *tstate_p = tstate;
+ return _PyStatus_OK();
+
+error:
+ *tstate_p = NULL;
+
+ /* Oops, it didn't work. Undo it all. */
+ PyErr_PrintEx(0);
+ PyThreadState_Clear(tstate);
+ PyThreadState_Delete(tstate);
+ PyInterpreterState_Delete(interp);
+ PyThreadState_Swap(save_tstate);
+
+ return status;
+}
+
+PyThreadState *
+_Py_NewInterpreter(int isolated_subinterpreter)
+{
+ PyThreadState *tstate = NULL;
+ PyStatus status = new_interpreter(&tstate, isolated_subinterpreter);
+ if (_PyStatus_EXCEPTION(status)) {
+ Py_ExitStatusException(status);
+ }
+ return tstate;
+
+}
+
+PyThreadState *
+Py_NewInterpreter(void)
+{
+ return _Py_NewInterpreter(0);
+}
+
+/* Delete an interpreter and its last thread. This requires that the
+ given thread state is current, that the thread has no remaining
+ frames, and that it is its interpreter's only remaining thread.
+ It is a fatal error to violate these constraints.
+
+ (Py_FinalizeEx() doesn't have these constraints -- it zaps
+ everything, regardless.)
+
+ Locking: as above.
+
+*/
+
+void
+Py_EndInterpreter(PyThreadState *tstate)
+{
+ PyInterpreterState *interp = tstate->interp;
+
+ if (tstate != _PyThreadState_GET()) {
+ Py_FatalError("thread is not current");
+ }
+ if (tstate->frame != NULL) {
+ Py_FatalError("thread still has a frame");
+ }
+ interp->finalizing = 1;
+
+ // Wrap up existing "threading"-module-created, non-daemon threads.
+ wait_for_thread_shutdown(tstate);
+
+ call_py_exitfuncs(tstate);
+
+ if (tstate != interp->tstate_head || tstate->next != NULL) {
+ Py_FatalError("not the last thread");
+ }
+
+ _PyImport_Cleanup(tstate);
+ finalize_interp_clear(tstate);
+ finalize_interp_delete(tstate);
+}
+
+/* Add the __main__ module */
+
+static PyStatus
+add_main_module(PyInterpreterState *interp)
+{
+ PyObject *m, *d, *loader, *ann_dict;
+ m = PyImport_AddModule("__main__");
+ if (m == NULL)
+ return _PyStatus_ERR("can't create __main__ module");
+
+ d = PyModule_GetDict(m);
+ ann_dict = PyDict_New();
+ if ((ann_dict == NULL) ||
+ (PyDict_SetItemString(d, "__annotations__", ann_dict) < 0)) {
+ return _PyStatus_ERR("Failed to initialize __main__.__annotations__");
+ }
+ Py_DECREF(ann_dict);
+
+ if (PyDict_GetItemString(d, "__builtins__") == NULL) {
+ PyObject *bimod = PyImport_ImportModule("builtins");
+ if (bimod == NULL) {
+ return _PyStatus_ERR("Failed to retrieve builtins module");
+ }
+ if (PyDict_SetItemString(d, "__builtins__", bimod) < 0) {
+ return _PyStatus_ERR("Failed to initialize __main__.__builtins__");
+ }
+ Py_DECREF(bimod);
+ }
+
+ /* Main is a little special - imp.is_builtin("__main__") will return
+ * False, but BuiltinImporter is still the most appropriate initial
+ * setting for its __loader__ attribute. A more suitable value will
+ * be set if __main__ gets further initialized later in the startup
+ * process.
+ */
+ loader = PyDict_GetItemString(d, "__loader__");
+ if (loader == NULL || loader == Py_None) {
+ PyObject *loader = PyObject_GetAttrString(interp->importlib,
+ "BuiltinImporter");
+ if (loader == NULL) {
+ return _PyStatus_ERR("Failed to retrieve BuiltinImporter");
+ }
+ if (PyDict_SetItemString(d, "__loader__", loader) < 0) {
+ return _PyStatus_ERR("Failed to initialize __main__.__loader__");
+ }
+ Py_DECREF(loader);
+ }
+ return _PyStatus_OK();
+}
+
+/* Import the site module (not into __main__ though) */
+
+static PyStatus
+init_import_site(void)
+{
+ PyObject *m;
+ m = PyImport_ImportModule("site");
+ if (m == NULL) {
+ return _PyStatus_ERR("Failed to import the site module");
+ }
+ Py_DECREF(m);
+ return _PyStatus_OK();
+}
+
+/* Check if a file descriptor is valid or not.
+ Return 0 if the file descriptor is invalid, return non-zero otherwise. */
+static int
+is_valid_fd(int fd)
+{
+/* dup() is faster than fstat(): fstat() can require input/output operations,
+ whereas dup() doesn't. There is a low risk of EMFILE/ENFILE at Python
+ startup. Problem: dup() doesn't check if the file descriptor is valid on
+ some platforms.
+
+ bpo-30225: On macOS Tiger, when stdout is redirected to a pipe and the other
+ side of the pipe is closed, dup(1) succeed, whereas fstat(1, &st) fails with
+ EBADF. FreeBSD has similar issue (bpo-32849).
+
+ Only use dup() on platforms where dup() is enough to detect invalid FD in
+ corner cases: on Linux and Windows (bpo-32849). */
+#if defined(__linux__) || defined(MS_WINDOWS)
+ if (fd < 0) {
+ return 0;
+ }
+ int fd2;
+
+ _Py_BEGIN_SUPPRESS_IPH
+ fd2 = dup(fd);
+ if (fd2 >= 0) {
+ close(fd2);
+ }
+ _Py_END_SUPPRESS_IPH
+
+ return (fd2 >= 0);
+#else
+ struct stat st;
+ return (fstat(fd, &st) == 0);
+#endif
+}
+
+/* returns Py_None if the fd is not valid */
+static PyObject*
+create_stdio(const PyConfig *config, PyObject* io,
+ int fd, int write_mode, const char* name,
+ const wchar_t* encoding, const wchar_t* errors)
+{
+ PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL, *res;
+ const char* mode;
+ const char* newline;
+ PyObject *line_buffering, *write_through;
+ int buffering, isatty;
+ _Py_IDENTIFIER(open);
+ _Py_IDENTIFIER(isatty);
+ _Py_IDENTIFIER(TextIOWrapper);
+ _Py_IDENTIFIER(mode);
+ const int buffered_stdio = config->buffered_stdio;
+
+ if (!is_valid_fd(fd))
+ Py_RETURN_NONE;
+
+ /* stdin is always opened in buffered mode, first because it shouldn't
+ make a difference in common use cases, second because TextIOWrapper
+ depends on the presence of a read1() method which only exists on
+ buffered streams.
+ */
+ if (!buffered_stdio && write_mode)
+ buffering = 0;
+ else
+ buffering = -1;
+ if (write_mode)
+ mode = "wb";
+ else
+ mode = "rb";
+ buf = _PyObject_CallMethodId(io, &PyId_open, "isiOOOO",
+ fd, mode, buffering,
+ Py_None, Py_None, /* encoding, errors */
+ Py_None, Py_False); /* newline, closefd */
+ if (buf == NULL)
+ goto error;
+
+ if (buffering) {
+ _Py_IDENTIFIER(raw);
+ raw = _PyObject_GetAttrId(buf, &PyId_raw);
+ if (raw == NULL)
+ goto error;
+ }
+ else {
+ raw = buf;
+ Py_INCREF(raw);
+ }
+
+#ifdef MS_WINDOWS
+ /* Windows console IO is always UTF-8 encoded */
+ if (PyWindowsConsoleIO_Check(raw))
+ encoding = L"utf-8";
+#endif
+
+ text = PyUnicode_FromString(name);
+ if (text == NULL || _PyObject_SetAttrId(raw, &PyId_name, text) < 0)
+ goto error;
+ res = _PyObject_CallMethodIdNoArgs(raw, &PyId_isatty);
+ if (res == NULL)
+ goto error;
+ isatty = PyObject_IsTrue(res);
+ Py_DECREF(res);
+ if (isatty == -1)
+ goto error;
+ if (!buffered_stdio)
+ write_through = Py_True;
+ else
+ write_through = Py_False;
+ if (buffered_stdio && (isatty || fd == fileno(stderr)))
+ line_buffering = Py_True;
+ else
+ line_buffering = Py_False;
+
+ Py_CLEAR(raw);
+ Py_CLEAR(text);
+
+#ifdef MS_WINDOWS
+ /* sys.stdin: enable universal newline mode, translate "\r\n" and "\r"
+ newlines to "\n".
+ sys.stdout and sys.stderr: translate "\n" to "\r\n". */
+ newline = NULL;
+#else
+ /* sys.stdin: split lines at "\n".
+ sys.stdout and sys.stderr: don't translate newlines (use "\n"). */
+ newline = "\n";
+#endif
+
+ PyObject *encoding_str = PyUnicode_FromWideChar(encoding, -1);
+ if (encoding_str == NULL) {
+ Py_CLEAR(buf);
+ goto error;
+ }
+
+ PyObject *errors_str = PyUnicode_FromWideChar(errors, -1);
+ if (errors_str == NULL) {
+ Py_CLEAR(buf);
+ Py_CLEAR(encoding_str);
+ goto error;
+ }
+
+ stream = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "OOOsOO",
+ buf, encoding_str, errors_str,
+ newline, line_buffering, write_through);
+ Py_CLEAR(buf);
+ Py_CLEAR(encoding_str);
+ Py_CLEAR(errors_str);
+ if (stream == NULL)
+ goto error;
+
+ if (write_mode)
+ mode = "w";
+ else
+ mode = "r";
+ text = PyUnicode_FromString(mode);
+ if (!text || _PyObject_SetAttrId(stream, &PyId_mode, text) < 0)
+ goto error;
+ Py_CLEAR(text);
+ return stream;
+
+error:
+ Py_XDECREF(buf);
+ Py_XDECREF(stream);
+ Py_XDECREF(text);
+ Py_XDECREF(raw);
+
+ if (PyErr_ExceptionMatches(PyExc_OSError) && !is_valid_fd(fd)) {
+ /* Issue #24891: the file descriptor was closed after the first
+ is_valid_fd() check was called. Ignore the OSError and set the
+ stream to None. */
+ PyErr_Clear();
+ Py_RETURN_NONE;
+ }
+ return NULL;
+}
+
+/* Set builtins.open to io.OpenWrapper */
+static PyStatus
+init_set_builtins_open(void)
+{
+ PyObject *iomod = NULL, *wrapper;
+ PyObject *bimod = NULL;
+ PyStatus res = _PyStatus_OK();
+
+ if (!(iomod = PyImport_ImportModule("io"))) {
+ goto error;
+ }
+
+ if (!(bimod = PyImport_ImportModule("builtins"))) {
+ goto error;
+ }
+
+ if (!(wrapper = PyObject_GetAttrString(iomod, "OpenWrapper"))) {
+ goto error;
+ }
+
+ /* Set builtins.open */
+ if (PyObject_SetAttrString(bimod, "open", wrapper) == -1) {
+ Py_DECREF(wrapper);
+ goto error;
+ }
+ Py_DECREF(wrapper);
+ goto done;
+
+error:
+ res = _PyStatus_ERR("can't initialize io.open");
+
+done:
+ Py_XDECREF(bimod);
+ Py_XDECREF(iomod);
+ return res;
+}
+
+
+/* Initialize sys.stdin, stdout, stderr and builtins.open */
+static PyStatus
+init_sys_streams(PyThreadState *tstate)
+{
+ PyObject *iomod = NULL;
+ PyObject *m;
+ PyObject *std = NULL;
+ int fd;
+ PyObject * encoding_attr;
+ PyStatus res = _PyStatus_OK();
+ const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
+
+ /* Check that stdin is not a directory
+ Using shell redirection, you can redirect stdin to a directory,
+ crashing the Python interpreter. Catch this common mistake here
+ and output a useful error message. Note that under MS Windows,
+ the shell already prevents that. */
+#ifndef MS_WINDOWS
+ struct _Py_stat_struct sb;
+ if (_Py_fstat_noraise(fileno(stdin), &sb) == 0 &&
+ S_ISDIR(sb.st_mode)) {
+ return _PyStatus_ERR("<stdin> is a directory, cannot continue");
+ }
+#endif
+
+ /* Hack to avoid a nasty recursion issue when Python is invoked
+ in verbose mode: pre-import the Latin-1 and UTF-8 codecs */
+ if ((m = PyImport_ImportModule("encodings.utf_8")) == NULL) {
+ goto error;
+ }
+ Py_DECREF(m);
+
+ if (!(m = PyImport_ImportModule("encodings.latin_1"))) {
+ goto error;
+ }
+ Py_DECREF(m);
+
+ if (!(iomod = PyImport_ImportModule("io"))) {
+ goto error;
+ }
+
+ /* Set sys.stdin */
+ fd = fileno(stdin);
+ /* Under some conditions stdin, stdout and stderr may not be connected
+ * and fileno() may point to an invalid file descriptor. For example
+ * GUI apps don't have valid standard streams by default.
+ */
+ std = create_stdio(config, iomod, fd, 0, "<stdin>",
+ config->stdio_encoding,
+ config->stdio_errors);
+ if (std == NULL)
+ goto error;
+ PySys_SetObject("__stdin__", std);
+ _PySys_SetObjectId(&PyId_stdin, std);
+ Py_DECREF(std);
+
+ /* Set sys.stdout */
+ fd = fileno(stdout);
+ std = create_stdio(config, iomod, fd, 1, "<stdout>",
+ config->stdio_encoding,
+ config->stdio_errors);
+ if (std == NULL)
+ goto error;
+ PySys_SetObject("__stdout__", std);
+ _PySys_SetObjectId(&PyId_stdout, std);
+ Py_DECREF(std);
+
+#if 1 /* Disable this if you have trouble debugging bootstrap stuff */
+ /* Set sys.stderr, replaces the preliminary stderr */
+ fd = fileno(stderr);
+ std = create_stdio(config, iomod, fd, 1, "<stderr>",
+ config->stdio_encoding,
+ L"backslashreplace");
+ if (std == NULL)
+ goto error;
+
+ /* Same as hack above, pre-import stderr's codec to avoid recursion
+ when import.c tries to write to stderr in verbose mode. */
+ encoding_attr = PyObject_GetAttrString(std, "encoding");
+ if (encoding_attr != NULL) {
+ const char *std_encoding = PyUnicode_AsUTF8(encoding_attr);
+ if (std_encoding != NULL) {
+ PyObject *codec_info = _PyCodec_Lookup(std_encoding);
+ Py_XDECREF(codec_info);
+ }
+ Py_DECREF(encoding_attr);
+ }
+ _PyErr_Clear(tstate); /* Not a fatal error if codec isn't available */
+
+ if (PySys_SetObject("__stderr__", std) < 0) {
+ Py_DECREF(std);
+ goto error;
+ }
+ if (_PySys_SetObjectId(&PyId_stderr, std) < 0) {
+ Py_DECREF(std);
+ goto error;
+ }
+ Py_DECREF(std);
+#endif
+
+ goto done;
+
+error:
+ res = _PyStatus_ERR("can't initialize sys standard streams");
+
+done:
+ _Py_ClearStandardStreamEncoding();
+ Py_XDECREF(iomod);
+ return res;
+}
+
+
+static void
+_Py_FatalError_DumpTracebacks(int fd, PyInterpreterState *interp,
+ PyThreadState *tstate)
+{
+ fputc('\n', stderr);
+ fflush(stderr);
+
+ /* display the current Python stack */
+ _Py_DumpTracebackThreads(fd, interp, tstate);
+}
+
+/* Print the current exception (if an exception is set) with its traceback,
+ or display the current Python stack.
+
+ Don't call PyErr_PrintEx() and the except hook, because Py_FatalError() is
+ called on catastrophic cases.
+
+ Return 1 if the traceback was displayed, 0 otherwise. */
+
+static int
+_Py_FatalError_PrintExc(PyThreadState *tstate)
+{
+ PyObject *ferr, *res;
+ PyObject *exception, *v, *tb;
+ int has_tb;
+
+ _PyErr_Fetch(tstate, &exception, &v, &tb);
+ if (exception == NULL) {
+ /* No current exception */
+ return 0;
+ }
+
+ ferr = _PySys_GetObjectId(&PyId_stderr);
+ if (ferr == NULL || ferr == Py_None) {
+ /* sys.stderr is not set yet or set to None,
+ no need to try to display the exception */
+ return 0;
+ }
+
+ _PyErr_NormalizeException(tstate, &exception, &v, &tb);
+ if (tb == NULL) {
+ tb = Py_None;
+ Py_INCREF(tb);
+ }
+ PyException_SetTraceback(v, tb);
+ if (exception == NULL) {
+ /* PyErr_NormalizeException() failed */
+ return 0;
+ }
+
+ has_tb = (tb != Py_None);
+ PyErr_Display(exception, v, tb);
+ Py_XDECREF(exception);
+ Py_XDECREF(v);
+ Py_XDECREF(tb);
+
+ /* sys.stderr may be buffered: call sys.stderr.flush() */
+ res = _PyObject_CallMethodIdNoArgs(ferr, &PyId_flush);
+ if (res == NULL) {
+ _PyErr_Clear(tstate);
+ }
+ else {
+ Py_DECREF(res);
+ }
+
+ return has_tb;
+}
+
+/* Print fatal error message and abort */
+
+#ifdef MS_WINDOWS
+static void
+fatal_output_debug(const char *msg)
+{
+ /* buffer of 256 bytes allocated on the stack */
+ WCHAR buffer[256 / sizeof(WCHAR)];
+ size_t buflen = Py_ARRAY_LENGTH(buffer) - 1;
+ size_t msglen;
+
+ OutputDebugStringW(L"Fatal Python error: ");
+
+ msglen = strlen(msg);
+ while (msglen) {
+ size_t i;
+
+ if (buflen > msglen) {
+ buflen = msglen;
+ }
+
+ /* Convert the message to wchar_t. This uses a simple one-to-one
+ conversion, assuming that the this error message actually uses
+ ASCII only. If this ceases to be true, we will have to convert. */
+ for (i=0; i < buflen; ++i) {
+ buffer[i] = msg[i];
+ }
+ buffer[i] = L'\0';
+ OutputDebugStringW(buffer);
+
+ msg += buflen;
+ msglen -= buflen;
+ }
+ OutputDebugStringW(L"\n");
+}
+#endif
+
+
+static void
+fatal_error_dump_runtime(FILE *stream, _PyRuntimeState *runtime)
+{
+ fprintf(stream, "Python runtime state: ");
+ PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(runtime);
+ if (finalizing) {
+ fprintf(stream, "finalizing (tstate=%p)", finalizing);
+ }
+ else if (runtime->initialized) {
+ fprintf(stream, "initialized");
+ }
+ else if (runtime->core_initialized) {
+ fprintf(stream, "core initialized");
+ }
+ else if (runtime->preinitialized) {
+ fprintf(stream, "preinitialized");
+ }
+ else if (runtime->preinitializing) {
+ fprintf(stream, "preinitializing");
+ }
+ else {
+ fprintf(stream, "unknown");
+ }
+ fprintf(stream, "\n");
+ fflush(stream);
+}
+
+
+static inline void _Py_NO_RETURN
+fatal_error_exit(int status)
+{
+ if (status < 0) {
+#if defined(MS_WINDOWS) && defined(_DEBUG)
+ DebugBreak();
+#endif
+ abort();
+ }
+ else {
+ exit(status);
+ }
+}
+
+
+static void _Py_NO_RETURN
+fatal_error(FILE *stream, int header, const char *prefix, const char *msg,
+ int status)
+{
+ const int fd = fileno(stream);
+ static int reentrant = 0;
+
+ if (reentrant) {
+ /* Py_FatalError() caused a second fatal error.
+ Example: flush_std_files() raises a recursion error. */
+ fatal_error_exit(status);
+ }
+ reentrant = 1;
+
+ if (header) {
+ fprintf(stream, "Fatal Python error: ");
+ if (prefix) {
+ fputs(prefix, stream);
+ fputs(": ", stream);
+ }
+ if (msg) {
+ fputs(msg, stream);
+ }
+ else {
+ fprintf(stream, "<message not set>");
+ }
+ fputs("\n", stream);
+ fflush(stream);
+ }
+
+ _PyRuntimeState *runtime = &_PyRuntime;
+ fatal_error_dump_runtime(stream, runtime);
+
+ PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
+ PyInterpreterState *interp = NULL;
+ if (tstate != NULL) {
+ interp = tstate->interp;
+ }
+
+ /* Check if the current thread has a Python thread state
+ and holds the GIL.
+
+ tss_tstate is NULL if Py_FatalError() is called from a C thread which
+ has no Python thread state.
+
+ tss_tstate != tstate if the current Python thread does not hold the GIL.
+ */
+ PyThreadState *tss_tstate = PyGILState_GetThisThreadState();
+ int has_tstate_and_gil = (tss_tstate != NULL && tss_tstate == tstate);
+ if (has_tstate_and_gil) {
+ /* If an exception is set, print the exception with its traceback */
+ if (!_Py_FatalError_PrintExc(tss_tstate)) {
+ /* No exception is set, or an exception is set without traceback */
+ _Py_FatalError_DumpTracebacks(fd, interp, tss_tstate);
+ }
+ }
+ else {
+ _Py_FatalError_DumpTracebacks(fd, interp, tss_tstate);
+ }
+
+ /* The main purpose of faulthandler is to display the traceback.
+ This function already did its best to display a traceback.
+ Disable faulthandler to prevent writing a second traceback
+ on abort(). */
+ _PyFaulthandler_Fini();
+
+ /* Check if the current Python thread hold the GIL */
+ if (has_tstate_and_gil) {
+ /* Flush sys.stdout and sys.stderr */
+ flush_std_files();
+ }
+
+#ifdef MS_WINDOWS
+ fatal_output_debug(msg);
+#endif /* MS_WINDOWS */
+
+ fatal_error_exit(status);
+}
+
+
+#undef Py_FatalError
+
+void _Py_NO_RETURN
+Py_FatalError(const char *msg)
+{
+ fatal_error(stderr, 1, NULL, msg, -1);
+}
+
+
+void _Py_NO_RETURN
+_Py_FatalErrorFunc(const char *func, const char *msg)
+{
+ fatal_error(stderr, 1, func, msg, -1);
+}
+
+
+void _Py_NO_RETURN
+_Py_FatalErrorFormat(const char *func, const char *format, ...)
+{
+ static int reentrant = 0;
+ if (reentrant) {
+ /* _Py_FatalErrorFormat() caused a second fatal error */
+ fatal_error_exit(-1);
+ }
+ reentrant = 1;
+
+ FILE *stream = stderr;
+ fprintf(stream, "Fatal Python error: ");
+ if (func) {
+ fputs(func, stream);
+ fputs(": ", stream);
+ }
+ fflush(stream);
+
+ va_list vargs;
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, format);
+#else
+ va_start(vargs);
+#endif
+ vfprintf(stream, format, vargs);
+ va_end(vargs);
+
+ fputs("\n", stream);
+ fflush(stream);
+
+ fatal_error(stream, 0, NULL, NULL, -1);
+}
+
+
+void _Py_NO_RETURN
+Py_ExitStatusException(PyStatus status)
+{
+ if (_PyStatus_IS_EXIT(status)) {
+ exit(status.exitcode);
+ }
+ else if (_PyStatus_IS_ERROR(status)) {
+ fatal_error(stderr, 1, status.func, status.err_msg, 1);
+ }
+ else {
+ Py_FatalError("Py_ExitStatusException() must not be called on success");
+ }
+}
+
+/* Clean up and exit */
+
+/* For the atexit module. */
+void _Py_PyAtExit(void (*func)(PyObject *), PyObject *module)
+{
+ PyInterpreterState *is = _PyInterpreterState_GET();
+
+ /* Guard against API misuse (see bpo-17852) */
+ assert(is->pyexitfunc == NULL || is->pyexitfunc == func);
+
+ is->pyexitfunc = func;
+ is->pyexitmodule = module;
+}
+
+static void
+call_py_exitfuncs(PyThreadState *tstate)
+{
+ PyInterpreterState *interp = tstate->interp;
+ if (interp->pyexitfunc == NULL)
+ return;
+
+ (*interp->pyexitfunc)(interp->pyexitmodule);
+ _PyErr_Clear(tstate);
+}
+
+/* Wait until threading._shutdown completes, provided
+ the threading module was imported in the first place.
+ The shutdown routine will wait until all non-daemon
+ "threading" threads have completed. */
+static void
+wait_for_thread_shutdown(PyThreadState *tstate)
+{
+ _Py_IDENTIFIER(_shutdown);
+ PyObject *result;
+ PyObject *threading = _PyImport_GetModuleId(&PyId_threading);
+ if (threading == NULL) {
+ if (_PyErr_Occurred(tstate)) {
+ PyErr_WriteUnraisable(NULL);
+ }
+ /* else: threading not imported */
+ return;
+ }
+ result = _PyObject_CallMethodIdNoArgs(threading, &PyId__shutdown);
+ if (result == NULL) {
+ PyErr_WriteUnraisable(threading);
+ }
+ else {
+ Py_DECREF(result);
+ }
+ Py_DECREF(threading);
+}
+
+#define NEXITFUNCS 32
+int Py_AtExit(void (*func)(void))
+{
+ if (_PyRuntime.nexitfuncs >= NEXITFUNCS)
+ return -1;
+ _PyRuntime.exitfuncs[_PyRuntime.nexitfuncs++] = func;
+ return 0;
+}
+
+static void
+call_ll_exitfuncs(_PyRuntimeState *runtime)
+{
+ while (runtime->nexitfuncs > 0) {
+ /* pop last function from the list */
+ runtime->nexitfuncs--;
+ void (*exitfunc)(void) = runtime->exitfuncs[runtime->nexitfuncs];
+ runtime->exitfuncs[runtime->nexitfuncs] = NULL;
+
+ exitfunc();
+ }
+
+ fflush(stdout);
+ fflush(stderr);
+}
+
+void _Py_NO_RETURN
+Py_Exit(int sts)
+{
+ if (Py_FinalizeEx() < 0) {
+ sts = 120;
+ }
+
+ exit(sts);
+}
+
+
+/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL.
+ *
+ * All of the code in this function must only use async-signal-safe functions,
+ * listed at `man 7 signal` or
+ * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html.
+ *
+ * If this function is updated, update also _posix_spawn() of subprocess.py.
+ */
+void
+_Py_RestoreSignals(void)
+{
+#ifdef SIGPIPE
+ PyOS_setsig(SIGPIPE, SIG_DFL);
+#endif
+#ifdef SIGXFZ
+ PyOS_setsig(SIGXFZ, SIG_DFL);
+#endif
+#ifdef SIGXFSZ
+ PyOS_setsig(SIGXFSZ, SIG_DFL);
+#endif
+}
+
+
+/*
+ * The file descriptor fd is considered ``interactive'' if either
+ * a) isatty(fd) is TRUE, or
+ * b) the -i flag was given, and the filename associated with
+ * the descriptor is NULL or "<stdin>" or "???".
+ */
+int
+Py_FdIsInteractive(FILE *fp, const char *filename)
+{
+ if (isatty((int)fileno(fp)))
+ return 1;
+ if (!Py_InteractiveFlag)
+ return 0;
+ return (filename == NULL) ||
+ (strcmp(filename, "<stdin>") == 0) ||
+ (strcmp(filename, "???") == 0);
+}
+
+
+/* Wrappers around sigaction() or signal(). */
+
+PyOS_sighandler_t
+PyOS_getsig(int sig)
+{
+#ifdef HAVE_SIGACTION
+ struct sigaction context;
+ if (sigaction(sig, NULL, &context) == -1)
+ return SIG_ERR;
+ return context.sa_handler;
+#else
+ PyOS_sighandler_t handler;
+/* Special signal handling for the secure CRT in Visual Studio 2005 */
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ switch (sig) {
+ /* Only these signals are valid */
+ case SIGINT:
+ case SIGILL:
+ case SIGFPE:
+ case SIGSEGV:
+ case SIGTERM:
+ case SIGBREAK:
+ case SIGABRT:
+ break;
+ /* Don't call signal() with other values or it will assert */
+ default:
+ return SIG_ERR;
+ }
+#endif /* _MSC_VER && _MSC_VER >= 1400 */
+ handler = signal(sig, SIG_IGN);
+ if (handler != SIG_ERR)
+ signal(sig, handler);
+ return handler;
+#endif
+}
+
+/*
+ * All of the code in this function must only use async-signal-safe functions,
+ * listed at `man 7 signal` or
+ * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html.
+ */
+PyOS_sighandler_t
+PyOS_setsig(int sig, PyOS_sighandler_t handler)
+{
+#ifdef HAVE_SIGACTION
+ /* Some code in Modules/signalmodule.c depends on sigaction() being
+ * used here if HAVE_SIGACTION is defined. Fix that if this code
+ * changes to invalidate that assumption.
+ */
+ struct sigaction context, ocontext;
+ context.sa_handler = handler;
+ sigemptyset(&context.sa_mask);
+ context.sa_flags = 0;
+ if (sigaction(sig, &context, &ocontext) == -1)
+ return SIG_ERR;
+ return ocontext.sa_handler;
+#else
+ PyOS_sighandler_t oldhandler;
+ oldhandler = signal(sig, handler);
+#ifdef HAVE_SIGINTERRUPT
+ siginterrupt(sig, 1);
+#endif
+ return oldhandler;
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/contrib/tools/python3/src/Python/pymath.c b/contrib/tools/python3/src/Python/pymath.c
new file mode 100644
index 00000000000..a08a0e79615
--- /dev/null
+++ b/contrib/tools/python3/src/Python/pymath.c
@@ -0,0 +1,96 @@
+#include "Python.h"
+
+#ifdef X87_DOUBLE_ROUNDING
+/* On x86 platforms using an x87 FPU, this function is called from the
+ Py_FORCE_DOUBLE macro (defined in pymath.h) to force a floating-point
+ number out of an 80-bit x87 FPU register and into a 64-bit memory location,
+ thus rounding from extended precision to double precision. */
+double _Py_force_double(double x)
+{
+ volatile double y;
+ y = x;
+ return y;
+}
+#endif
+
+#ifdef HAVE_GCC_ASM_FOR_X87
+
+/* inline assembly for getting and setting the 387 FPU control word on
+ gcc/x86 */
+#ifdef _Py_MEMORY_SANITIZER
+__attribute__((no_sanitize_memory))
+#endif
+unsigned short _Py_get_387controlword(void) {
+ unsigned short cw;
+ __asm__ __volatile__ ("fnstcw %0" : "=m" (cw));
+ return cw;
+}
+
+void _Py_set_387controlword(unsigned short cw) {
+ __asm__ __volatile__ ("fldcw %0" : : "m" (cw));
+}
+
+#endif
+
+
+#ifndef HAVE_HYPOT
+double hypot(double x, double y)
+{
+ double yx;
+
+ x = fabs(x);
+ y = fabs(y);
+ if (x < y) {
+ double temp = x;
+ x = y;
+ y = temp;
+ }
+ if (x == 0.)
+ return 0.;
+ else {
+ yx = y/x;
+ return x*sqrt(1.+yx*yx);
+ }
+}
+#endif /* HAVE_HYPOT */
+
+#ifndef HAVE_COPYSIGN
+double
+copysign(double x, double y)
+{
+ /* use atan2 to distinguish -0. from 0. */
+ if (y > 0. || (y == 0. && atan2(y, -1.) > 0.)) {
+ return fabs(x);
+ } else {
+ return -fabs(x);
+ }
+}
+#endif /* HAVE_COPYSIGN */
+
+#ifndef HAVE_ROUND
+double
+round(double x)
+{
+ double absx, y;
+ absx = fabs(x);
+ y = floor(absx);
+ if (absx - y >= 0.5)
+ y += 1.0;
+ return copysign(y, x);
+}
+#endif /* HAVE_ROUND */
+
+static const unsigned int BitLengthTable[32] = {
+ 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+};
+
+unsigned int _Py_bit_length(unsigned long d) {
+ unsigned int d_bits = 0;
+ while (d >= 32) {
+ d_bits += 6;
+ d >>= 6;
+ }
+ d_bits += BitLengthTable[d];
+ return d_bits;
+}
diff --git a/contrib/tools/python3/src/Python/pystate.c b/contrib/tools/python3/src/Python/pystate.c
new file mode 100644
index 00000000000..c3520c336a7
--- /dev/null
+++ b/contrib/tools/python3/src/Python/pystate.c
@@ -0,0 +1,1833 @@
+
+/* Thread and interpreter state structures and their interfaces */
+
+#include "Python.h"
+#include "pycore_ceval.h"
+#include "pycore_initconfig.h"
+#include "pycore_pyerrors.h"
+#include "pycore_pylifecycle.h"
+#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
+#include "pycore_pystate.h" // _PyThreadState_GET()
+#include "pycore_sysmodule.h"
+
+/* --------------------------------------------------------------------------
+CAUTION
+
+Always use PyMem_RawMalloc() and PyMem_RawFree() directly in this file. A
+number of these functions are advertised as safe to call when the GIL isn't
+held, and in a debug build Python redirects (e.g.) PyMem_NEW (etc) to Python's
+debugging obmalloc functions. Those aren't thread-safe (they rely on the GIL
+to avoid the expense of doing their own locking).
+-------------------------------------------------------------------------- */
+
+#ifdef HAVE_DLOPEN
+#ifdef HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+#if !HAVE_DECL_RTLD_LAZY
+#define RTLD_LAZY 1
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define _PyRuntimeGILState_GetThreadState(gilstate) \
+ ((PyThreadState*)_Py_atomic_load_relaxed(&(gilstate)->tstate_current))
+#define _PyRuntimeGILState_SetThreadState(gilstate, value) \
+ _Py_atomic_store_relaxed(&(gilstate)->tstate_current, \
+ (uintptr_t)(value))
+
+/* Forward declarations */
+static PyThreadState *_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate);
+static void _PyThreadState_Delete(PyThreadState *tstate, int check_current);
+
+
+static PyStatus
+_PyRuntimeState_Init_impl(_PyRuntimeState *runtime)
+{
+ /* We preserve the hook across init, because there is
+ currently no public API to set it between runtime
+ initialization and interpreter initialization. */
+ void *open_code_hook = runtime->open_code_hook;
+ void *open_code_userdata = runtime->open_code_userdata;
+ _Py_AuditHookEntry *audit_hook_head = runtime->audit_hook_head;
+
+ memset(runtime, 0, sizeof(*runtime));
+
+ runtime->open_code_hook = open_code_hook;
+ runtime->open_code_userdata = open_code_userdata;
+ runtime->audit_hook_head = audit_hook_head;
+
+ _PyEval_InitRuntimeState(&runtime->ceval);
+
+ PyPreConfig_InitPythonConfig(&runtime->preconfig);
+
+ runtime->gilstate.check_enabled = 1;
+
+ /* A TSS key must be initialized with Py_tss_NEEDS_INIT
+ in accordance with the specification. */
+ Py_tss_t initial = Py_tss_NEEDS_INIT;
+ runtime->gilstate.autoTSSkey = initial;
+
+ runtime->interpreters.mutex = PyThread_allocate_lock();
+ if (runtime->interpreters.mutex == NULL) {
+ return _PyStatus_ERR("Can't initialize threads for interpreter");
+ }
+ runtime->interpreters.next_id = -1;
+
+ runtime->xidregistry.mutex = PyThread_allocate_lock();
+ if (runtime->xidregistry.mutex == NULL) {
+ return _PyStatus_ERR("Can't initialize threads for cross-interpreter data registry");
+ }
+
+ // Set it to the ID of the main thread of the main interpreter.
+ runtime->main_thread = PyThread_get_thread_ident();
+
+ return _PyStatus_OK();
+}
+
+PyStatus
+_PyRuntimeState_Init(_PyRuntimeState *runtime)
+{
+ /* Force default allocator, since _PyRuntimeState_Fini() must
+ use the same allocator than this function. */
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ PyStatus status = _PyRuntimeState_Init_impl(runtime);
+
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+ return status;
+}
+
+void
+_PyRuntimeState_Fini(_PyRuntimeState *runtime)
+{
+ /* Force the allocator used by _PyRuntimeState_Init(). */
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ if (runtime->interpreters.mutex != NULL) {
+ PyThread_free_lock(runtime->interpreters.mutex);
+ runtime->interpreters.mutex = NULL;
+ }
+
+ if (runtime->xidregistry.mutex != NULL) {
+ PyThread_free_lock(runtime->xidregistry.mutex);
+ runtime->xidregistry.mutex = NULL;
+ }
+
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+}
+
+#ifdef HAVE_FORK
+/* This function is called from PyOS_AfterFork_Child to ensure that
+ * newly created child processes do not share locks with the parent.
+ */
+
+void
+_PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime)
+{
+ // This was initially set in _PyRuntimeState_Init().
+ runtime->main_thread = PyThread_get_thread_ident();
+
+ /* Force default allocator, since _PyRuntimeState_Fini() must
+ use the same allocator than this function. */
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ int interp_mutex = _PyThread_at_fork_reinit(&runtime->interpreters.mutex);
+ int xidregistry_mutex = _PyThread_at_fork_reinit(&runtime->xidregistry.mutex);
+
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ /* bpo-42540: id_mutex is freed by _PyInterpreterState_Delete, which does
+ * not force the default allocator. */
+ int main_interp_id_mutex = _PyThread_at_fork_reinit(&runtime->interpreters.main->id_mutex);
+
+ if (interp_mutex < 0) {
+ Py_FatalError("Can't initialize lock for runtime interpreters");
+ }
+
+ if (main_interp_id_mutex < 0) {
+ Py_FatalError("Can't initialize ID lock for main interpreter");
+ }
+
+ if (xidregistry_mutex < 0) {
+ Py_FatalError("Can't initialize lock for cross-interpreter data registry");
+ }
+}
+#endif
+
+#define HEAD_LOCK(runtime) \
+ PyThread_acquire_lock((runtime)->interpreters.mutex, WAIT_LOCK)
+#define HEAD_UNLOCK(runtime) \
+ PyThread_release_lock((runtime)->interpreters.mutex)
+
+/* Forward declaration */
+static void _PyGILState_NoteThreadState(
+ struct _gilstate_runtime_state *gilstate, PyThreadState* tstate);
+
+PyStatus
+_PyInterpreterState_Enable(_PyRuntimeState *runtime)
+{
+ struct pyinterpreters *interpreters = &runtime->interpreters;
+ interpreters->next_id = 0;
+
+ /* Py_Finalize() calls _PyRuntimeState_Fini() which clears the mutex.
+ Create a new mutex if needed. */
+ if (interpreters->mutex == NULL) {
+ /* Force default allocator, since _PyRuntimeState_Fini() must
+ use the same allocator than this function. */
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ interpreters->mutex = PyThread_allocate_lock();
+
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ if (interpreters->mutex == NULL) {
+ return _PyStatus_ERR("Can't initialize threads for interpreter");
+ }
+ }
+
+ return _PyStatus_OK();
+}
+
+PyInterpreterState *
+PyInterpreterState_New(void)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ /* tstate is NULL when Py_InitializeFromConfig() calls
+ PyInterpreterState_New() to create the main interpreter. */
+ if (_PySys_Audit(tstate, "cpython.PyInterpreterState_New", NULL) < 0) {
+ return NULL;
+ }
+
+ PyInterpreterState *interp = PyMem_RawCalloc(1, sizeof(PyInterpreterState));
+ if (interp == NULL) {
+ return NULL;
+ }
+
+ interp->id_refcount = -1;
+
+ /* Don't get runtime from tstate since tstate can be NULL */
+ _PyRuntimeState *runtime = &_PyRuntime;
+ interp->runtime = runtime;
+
+ if (_PyEval_InitState(&interp->ceval) < 0) {
+ goto out_of_memory;
+ }
+
+ _PyGC_InitState(&interp->gc);
+ PyConfig_InitPythonConfig(&interp->config);
+
+ interp->eval_frame = _PyEval_EvalFrameDefault;
+#ifdef HAVE_DLOPEN
+#if HAVE_DECL_RTLD_NOW
+ interp->dlopenflags = RTLD_NOW;
+#else
+ interp->dlopenflags = RTLD_LAZY;
+#endif
+#endif
+
+ struct pyinterpreters *interpreters = &runtime->interpreters;
+
+ HEAD_LOCK(runtime);
+ if (interpreters->next_id < 0) {
+ /* overflow or Py_Initialize() not called! */
+ if (tstate != NULL) {
+ _PyErr_SetString(tstate, PyExc_RuntimeError,
+ "failed to get an interpreter ID");
+ }
+ PyMem_RawFree(interp);
+ interp = NULL;
+ }
+ else {
+ interp->id = interpreters->next_id;
+ interpreters->next_id += 1;
+ interp->next = interpreters->head;
+ if (interpreters->main == NULL) {
+ interpreters->main = interp;
+ }
+ interpreters->head = interp;
+ }
+ HEAD_UNLOCK(runtime);
+
+ if (interp == NULL) {
+ return NULL;
+ }
+
+ interp->tstate_next_unique_id = 0;
+
+ interp->audit_hooks = NULL;
+
+ return interp;
+
+out_of_memory:
+ if (tstate != NULL) {
+ _PyErr_NoMemory(tstate);
+ }
+
+ PyMem_RawFree(interp);
+ return NULL;
+}
+
+
+void
+PyInterpreterState_Clear(PyInterpreterState *interp)
+{
+ _PyRuntimeState *runtime = interp->runtime;
+
+ /* Use the current Python thread state to call audit hooks,
+ not the current Python thread state of 'interp'. */
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (_PySys_Audit(tstate, "cpython.PyInterpreterState_Clear", NULL) < 0) {
+ _PyErr_Clear(tstate);
+ }
+
+ HEAD_LOCK(runtime);
+ for (PyThreadState *p = interp->tstate_head; p != NULL; p = p->next) {
+ PyThreadState_Clear(p);
+ }
+ HEAD_UNLOCK(runtime);
+
+ Py_CLEAR(interp->audit_hooks);
+
+ PyConfig_Clear(&interp->config);
+ Py_CLEAR(interp->codec_search_path);
+ Py_CLEAR(interp->codec_search_cache);
+ Py_CLEAR(interp->codec_error_registry);
+ Py_CLEAR(interp->modules);
+ Py_CLEAR(interp->modules_by_index);
+ Py_CLEAR(interp->sysdict);
+ Py_CLEAR(interp->builtins);
+ Py_CLEAR(interp->builtins_copy);
+ Py_CLEAR(interp->importlib);
+ Py_CLEAR(interp->import_func);
+ Py_CLEAR(interp->dict);
+#ifdef HAVE_FORK
+ Py_CLEAR(interp->before_forkers);
+ Py_CLEAR(interp->after_forkers_parent);
+ Py_CLEAR(interp->after_forkers_child);
+#endif
+ if (_PyRuntimeState_GetFinalizing(runtime) == NULL) {
+ _PyWarnings_Fini(interp);
+ }
+ // XXX Once we have one allocator per interpreter (i.e.
+ // per-interpreter GC) we must ensure that all of the interpreter's
+ // objects have been cleaned up at the point.
+}
+
+
+static void
+zapthreads(PyInterpreterState *interp, int check_current)
+{
+ PyThreadState *tstate;
+ /* No need to lock the mutex here because this should only happen
+ when the threads are all really dead (XXX famous last words). */
+ while ((tstate = interp->tstate_head) != NULL) {
+ _PyThreadState_Delete(tstate, check_current);
+ }
+}
+
+
+void
+PyInterpreterState_Delete(PyInterpreterState *interp)
+{
+ _PyRuntimeState *runtime = interp->runtime;
+ struct pyinterpreters *interpreters = &runtime->interpreters;
+ zapthreads(interp, 0);
+
+ _PyEval_FiniState(&interp->ceval);
+
+ /* Delete current thread. After this, many C API calls become crashy. */
+ _PyThreadState_Swap(&runtime->gilstate, NULL);
+
+ HEAD_LOCK(runtime);
+ PyInterpreterState **p;
+ for (p = &interpreters->head; ; p = &(*p)->next) {
+ if (*p == NULL) {
+ Py_FatalError("NULL interpreter");
+ }
+ if (*p == interp) {
+ break;
+ }
+ }
+ if (interp->tstate_head != NULL) {
+ Py_FatalError("remaining threads");
+ }
+ *p = interp->next;
+
+ if (interpreters->main == interp) {
+ interpreters->main = NULL;
+ if (interpreters->head != NULL) {
+ Py_FatalError("remaining subinterpreters");
+ }
+ }
+ HEAD_UNLOCK(runtime);
+
+ if (interp->id_mutex != NULL) {
+ PyThread_free_lock(interp->id_mutex);
+ }
+ PyMem_RawFree(interp);
+}
+
+
+/*
+ * Delete all interpreter states except the main interpreter. If there
+ * is a current interpreter state, it *must* be the main interpreter.
+ */
+void
+_PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime)
+{
+ struct _gilstate_runtime_state *gilstate = &runtime->gilstate;
+ struct pyinterpreters *interpreters = &runtime->interpreters;
+
+ PyThreadState *tstate = _PyThreadState_Swap(gilstate, NULL);
+ if (tstate != NULL && tstate->interp != interpreters->main) {
+ Py_FatalError("not main interpreter");
+ }
+
+ HEAD_LOCK(runtime);
+ PyInterpreterState *interp = interpreters->head;
+ interpreters->head = NULL;
+ while (interp != NULL) {
+ if (interp == interpreters->main) {
+ interpreters->main->next = NULL;
+ interpreters->head = interp;
+ interp = interp->next;
+ continue;
+ }
+
+ PyInterpreterState_Clear(interp); // XXX must activate?
+ zapthreads(interp, 1);
+ if (interp->id_mutex != NULL) {
+ PyThread_free_lock(interp->id_mutex);
+ }
+ PyInterpreterState *prev_interp = interp;
+ interp = interp->next;
+ PyMem_RawFree(prev_interp);
+ }
+ HEAD_UNLOCK(runtime);
+
+ if (interpreters->head == NULL) {
+ Py_FatalError("missing main interpreter");
+ }
+ _PyThreadState_Swap(gilstate, tstate);
+}
+
+
+PyInterpreterState *
+PyInterpreterState_Get(void)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ _Py_EnsureTstateNotNULL(tstate);
+ PyInterpreterState *interp = tstate->interp;
+ if (interp == NULL) {
+ Py_FatalError("no current interpreter");
+ }
+ return interp;
+}
+
+
+int64_t
+PyInterpreterState_GetID(PyInterpreterState *interp)
+{
+ if (interp == NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "no interpreter provided");
+ return -1;
+ }
+ return interp->id;
+}
+
+
+static PyInterpreterState *
+interp_look_up_id(_PyRuntimeState *runtime, int64_t requested_id)
+{
+ PyInterpreterState *interp = runtime->interpreters.head;
+ while (interp != NULL) {
+ int64_t id = PyInterpreterState_GetID(interp);
+ if (id < 0) {
+ return NULL;
+ }
+ if (requested_id == id) {
+ return interp;
+ }
+ interp = PyInterpreterState_Next(interp);
+ }
+ return NULL;
+}
+
+PyInterpreterState *
+_PyInterpreterState_LookUpID(int64_t requested_id)
+{
+ PyInterpreterState *interp = NULL;
+ if (requested_id >= 0) {
+ _PyRuntimeState *runtime = &_PyRuntime;
+ HEAD_LOCK(runtime);
+ interp = interp_look_up_id(runtime, requested_id);
+ HEAD_UNLOCK(runtime);
+ }
+ if (interp == NULL && !PyErr_Occurred()) {
+ PyErr_Format(PyExc_RuntimeError,
+ "unrecognized interpreter ID %lld", requested_id);
+ }
+ return interp;
+}
+
+
+int
+_PyInterpreterState_IDInitref(PyInterpreterState *interp)
+{
+ if (interp->id_mutex != NULL) {
+ return 0;
+ }
+ interp->id_mutex = PyThread_allocate_lock();
+ if (interp->id_mutex == NULL) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "failed to create init interpreter ID mutex");
+ return -1;
+ }
+ interp->id_refcount = 0;
+ return 0;
+}
+
+
+void
+_PyInterpreterState_IDIncref(PyInterpreterState *interp)
+{
+ if (interp->id_mutex == NULL) {
+ return;
+ }
+ PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK);
+ interp->id_refcount += 1;
+ PyThread_release_lock(interp->id_mutex);
+}
+
+
+void
+_PyInterpreterState_IDDecref(PyInterpreterState *interp)
+{
+ if (interp->id_mutex == NULL) {
+ return;
+ }
+ struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate;
+ PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK);
+ assert(interp->id_refcount != 0);
+ interp->id_refcount -= 1;
+ int64_t refcount = interp->id_refcount;
+ PyThread_release_lock(interp->id_mutex);
+
+ if (refcount == 0 && interp->requires_idref) {
+ // XXX Using the "head" thread isn't strictly correct.
+ PyThreadState *tstate = PyInterpreterState_ThreadHead(interp);
+ // XXX Possible GILState issues?
+ PyThreadState *save_tstate = _PyThreadState_Swap(gilstate, tstate);
+ Py_EndInterpreter(tstate);
+ _PyThreadState_Swap(gilstate, save_tstate);
+ }
+}
+
+int
+_PyInterpreterState_RequiresIDRef(PyInterpreterState *interp)
+{
+ return interp->requires_idref;
+}
+
+void
+_PyInterpreterState_RequireIDRef(PyInterpreterState *interp, int required)
+{
+ interp->requires_idref = required ? 1 : 0;
+}
+
+PyObject *
+_PyInterpreterState_GetMainModule(PyInterpreterState *interp)
+{
+ if (interp->modules == NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "interpreter not initialized");
+ return NULL;
+ }
+ return PyMapping_GetItemString(interp->modules, "__main__");
+}
+
+PyObject *
+PyInterpreterState_GetDict(PyInterpreterState *interp)
+{
+ if (interp->dict == NULL) {
+ interp->dict = PyDict_New();
+ if (interp->dict == NULL) {
+ PyErr_Clear();
+ }
+ }
+ /* Returning NULL means no per-interpreter dict is available. */
+ return interp->dict;
+}
+
+static PyThreadState *
+new_threadstate(PyInterpreterState *interp, int init)
+{
+ _PyRuntimeState *runtime = interp->runtime;
+ PyThreadState *tstate = (PyThreadState *)PyMem_RawMalloc(sizeof(PyThreadState));
+ if (tstate == NULL) {
+ return NULL;
+ }
+
+ tstate->interp = interp;
+
+ tstate->frame = NULL;
+ tstate->recursion_depth = 0;
+ tstate->overflowed = 0;
+ tstate->recursion_critical = 0;
+ tstate->stackcheck_counter = 0;
+ tstate->tracing = 0;
+ tstate->use_tracing = 0;
+ tstate->gilstate_counter = 0;
+ tstate->async_exc = NULL;
+ tstate->thread_id = PyThread_get_thread_ident();
+
+ tstate->dict = NULL;
+
+ tstate->curexc_type = NULL;
+ tstate->curexc_value = NULL;
+ tstate->curexc_traceback = NULL;
+
+ tstate->exc_state.exc_type = NULL;
+ tstate->exc_state.exc_value = NULL;
+ tstate->exc_state.exc_traceback = NULL;
+ tstate->exc_state.previous_item = NULL;
+ tstate->exc_info = &tstate->exc_state;
+
+ tstate->c_profilefunc = NULL;
+ tstate->c_tracefunc = NULL;
+ tstate->c_profileobj = NULL;
+ tstate->c_traceobj = NULL;
+
+ tstate->trash_delete_nesting = 0;
+ tstate->trash_delete_later = NULL;
+ tstate->on_delete = NULL;
+ tstate->on_delete_data = NULL;
+
+ tstate->coroutine_origin_tracking_depth = 0;
+
+ tstate->async_gen_firstiter = NULL;
+ tstate->async_gen_finalizer = NULL;
+
+ tstate->context = NULL;
+ tstate->context_ver = 1;
+
+ if (init) {
+ _PyThreadState_Init(tstate);
+ }
+
+ HEAD_LOCK(runtime);
+ tstate->id = ++interp->tstate_next_unique_id;
+ tstate->prev = NULL;
+ tstate->next = interp->tstate_head;
+ if (tstate->next)
+ tstate->next->prev = tstate;
+ interp->tstate_head = tstate;
+ HEAD_UNLOCK(runtime);
+
+ return tstate;
+}
+
+PyThreadState *
+PyThreadState_New(PyInterpreterState *interp)
+{
+ return new_threadstate(interp, 1);
+}
+
+PyThreadState *
+_PyThreadState_Prealloc(PyInterpreterState *interp)
+{
+ return new_threadstate(interp, 0);
+}
+
+void
+_PyThreadState_Init(PyThreadState *tstate)
+{
+ _PyGILState_NoteThreadState(&tstate->interp->runtime->gilstate, tstate);
+}
+
+PyObject*
+PyState_FindModule(struct PyModuleDef* module)
+{
+ Py_ssize_t index = module->m_base.m_index;
+ PyInterpreterState *state = _PyInterpreterState_GET();
+ PyObject *res;
+ if (module->m_slots) {
+ return NULL;
+ }
+ if (index == 0)
+ return NULL;
+ if (state->modules_by_index == NULL)
+ return NULL;
+ if (index >= PyList_GET_SIZE(state->modules_by_index))
+ return NULL;
+ res = PyList_GET_ITEM(state->modules_by_index, index);
+ return res==Py_None ? NULL : res;
+}
+
+int
+_PyState_AddModule(PyThreadState *tstate, PyObject* module, struct PyModuleDef* def)
+{
+ if (!def) {
+ assert(_PyErr_Occurred(tstate));
+ return -1;
+ }
+ if (def->m_slots) {
+ _PyErr_SetString(tstate,
+ PyExc_SystemError,
+ "PyState_AddModule called on module with slots");
+ return -1;
+ }
+
+ PyInterpreterState *interp = tstate->interp;
+ if (!interp->modules_by_index) {
+ interp->modules_by_index = PyList_New(0);
+ if (!interp->modules_by_index) {
+ return -1;
+ }
+ }
+
+ while (PyList_GET_SIZE(interp->modules_by_index) <= def->m_base.m_index) {
+ if (PyList_Append(interp->modules_by_index, Py_None) < 0) {
+ return -1;
+ }
+ }
+
+ Py_INCREF(module);
+ return PyList_SetItem(interp->modules_by_index,
+ def->m_base.m_index, module);
+}
+
+int
+PyState_AddModule(PyObject* module, struct PyModuleDef* def)
+{
+ if (!def) {
+ Py_FatalError("module definition is NULL");
+ return -1;
+ }
+
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyInterpreterState *interp = tstate->interp;
+ Py_ssize_t index = def->m_base.m_index;
+ if (interp->modules_by_index &&
+ index < PyList_GET_SIZE(interp->modules_by_index) &&
+ module == PyList_GET_ITEM(interp->modules_by_index, index))
+ {
+ _Py_FatalErrorFormat(__func__, "module %p already added", module);
+ return -1;
+ }
+ return _PyState_AddModule(tstate, module, def);
+}
+
+int
+PyState_RemoveModule(struct PyModuleDef* def)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyInterpreterState *interp = tstate->interp;
+
+ if (def->m_slots) {
+ _PyErr_SetString(tstate,
+ PyExc_SystemError,
+ "PyState_RemoveModule called on module with slots");
+ return -1;
+ }
+
+ Py_ssize_t index = def->m_base.m_index;
+ if (index == 0) {
+ Py_FatalError("invalid module index");
+ }
+ if (interp->modules_by_index == NULL) {
+ Py_FatalError("Interpreters module-list not accessible.");
+ }
+ if (index > PyList_GET_SIZE(interp->modules_by_index)) {
+ Py_FatalError("Module index out of bounds.");
+ }
+
+ Py_INCREF(Py_None);
+ return PyList_SetItem(interp->modules_by_index, index, Py_None);
+}
+
+/* Used by PyImport_Cleanup() */
+void
+_PyInterpreterState_ClearModules(PyInterpreterState *interp)
+{
+ if (!interp->modules_by_index) {
+ return;
+ }
+
+ Py_ssize_t i;
+ for (i = 0; i < PyList_GET_SIZE(interp->modules_by_index); i++) {
+ PyObject *m = PyList_GET_ITEM(interp->modules_by_index, i);
+ if (PyModule_Check(m)) {
+ /* cleanup the saved copy of module dicts */
+ PyModuleDef *md = PyModule_GetDef(m);
+ if (md) {
+ Py_CLEAR(md->m_base.m_copy);
+ }
+ }
+ }
+
+ /* Setting modules_by_index to NULL could be dangerous, so we
+ clear the list instead. */
+ if (PyList_SetSlice(interp->modules_by_index,
+ 0, PyList_GET_SIZE(interp->modules_by_index),
+ NULL)) {
+ PyErr_WriteUnraisable(interp->modules_by_index);
+ }
+}
+
+void
+PyThreadState_Clear(PyThreadState *tstate)
+{
+ int verbose = _PyInterpreterState_GetConfig(tstate->interp)->verbose;
+
+ if (verbose && tstate->frame != NULL) {
+ /* bpo-20526: After the main thread calls
+ _PyRuntimeState_SetFinalizing() in Py_FinalizeEx(), threads must
+ exit when trying to take the GIL. If a thread exit in the middle of
+ _PyEval_EvalFrameDefault(), tstate->frame is not reset to its
+ previous value. It is more likely with daemon threads, but it can
+ happen with regular threads if threading._shutdown() fails
+ (ex: interrupted by CTRL+C). */
+ fprintf(stderr,
+ "PyThreadState_Clear: warning: thread still has a frame\n");
+ }
+
+ /* Don't clear tstate->frame: it is a borrowed reference */
+
+ Py_CLEAR(tstate->dict);
+ Py_CLEAR(tstate->async_exc);
+
+ Py_CLEAR(tstate->curexc_type);
+ Py_CLEAR(tstate->curexc_value);
+ Py_CLEAR(tstate->curexc_traceback);
+
+ Py_CLEAR(tstate->exc_state.exc_type);
+ Py_CLEAR(tstate->exc_state.exc_value);
+ Py_CLEAR(tstate->exc_state.exc_traceback);
+
+ /* The stack of exception states should contain just this thread. */
+ if (verbose && tstate->exc_info != &tstate->exc_state) {
+ fprintf(stderr,
+ "PyThreadState_Clear: warning: thread still has a generator\n");
+ }
+
+ tstate->c_profilefunc = NULL;
+ tstate->c_tracefunc = NULL;
+ Py_CLEAR(tstate->c_profileobj);
+ Py_CLEAR(tstate->c_traceobj);
+
+ Py_CLEAR(tstate->async_gen_firstiter);
+ Py_CLEAR(tstate->async_gen_finalizer);
+
+ Py_CLEAR(tstate->context);
+
+ if (tstate->on_delete != NULL) {
+ tstate->on_delete(tstate->on_delete_data);
+ }
+}
+
+
+/* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */
+static void
+tstate_delete_common(PyThreadState *tstate,
+ struct _gilstate_runtime_state *gilstate)
+{
+ _Py_EnsureTstateNotNULL(tstate);
+ PyInterpreterState *interp = tstate->interp;
+ if (interp == NULL) {
+ Py_FatalError("NULL interpreter");
+ }
+ _PyRuntimeState *runtime = interp->runtime;
+
+ HEAD_LOCK(runtime);
+ if (tstate->prev) {
+ tstate->prev->next = tstate->next;
+ }
+ else {
+ interp->tstate_head = tstate->next;
+ }
+ if (tstate->next) {
+ tstate->next->prev = tstate->prev;
+ }
+ HEAD_UNLOCK(runtime);
+
+ if (gilstate->autoInterpreterState &&
+ PyThread_tss_get(&gilstate->autoTSSkey) == tstate)
+ {
+ PyThread_tss_set(&gilstate->autoTSSkey, NULL);
+ }
+}
+
+
+static void
+_PyThreadState_Delete(PyThreadState *tstate, int check_current)
+{
+ struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate;
+ if (check_current) {
+ if (tstate == _PyRuntimeGILState_GetThreadState(gilstate)) {
+ _Py_FatalErrorFormat(__func__, "tstate %p is still current", tstate);
+ }
+ }
+ tstate_delete_common(tstate, gilstate);
+ PyMem_RawFree(tstate);
+}
+
+
+void
+PyThreadState_Delete(PyThreadState *tstate)
+{
+ _PyThreadState_Delete(tstate, 1);
+}
+
+
+void
+_PyThreadState_DeleteCurrent(PyThreadState *tstate)
+{
+ _Py_EnsureTstateNotNULL(tstate);
+ struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate;
+ tstate_delete_common(tstate, gilstate);
+ _PyRuntimeGILState_SetThreadState(gilstate, NULL);
+ _PyEval_ReleaseLock(tstate);
+ PyMem_RawFree(tstate);
+}
+
+void
+PyThreadState_DeleteCurrent(void)
+{
+ struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate;
+ PyThreadState *tstate = _PyRuntimeGILState_GetThreadState(gilstate);
+ _PyThreadState_DeleteCurrent(tstate);
+}
+
+
+/*
+ * Delete all thread states except the one passed as argument.
+ * Note that, if there is a current thread state, it *must* be the one
+ * passed as argument. Also, this won't touch any other interpreters
+ * than the current one, since we don't know which thread state should
+ * be kept in those other interpreters.
+ */
+void
+_PyThreadState_DeleteExcept(_PyRuntimeState *runtime, PyThreadState *tstate)
+{
+ PyInterpreterState *interp = tstate->interp;
+
+ HEAD_LOCK(runtime);
+ /* Remove all thread states, except tstate, from the linked list of
+ thread states. This will allow calling PyThreadState_Clear()
+ without holding the lock. */
+ PyThreadState *list = interp->tstate_head;
+ if (list == tstate) {
+ list = tstate->next;
+ }
+ if (tstate->prev) {
+ tstate->prev->next = tstate->next;
+ }
+ if (tstate->next) {
+ tstate->next->prev = tstate->prev;
+ }
+ tstate->prev = tstate->next = NULL;
+ interp->tstate_head = tstate;
+ HEAD_UNLOCK(runtime);
+
+ /* Clear and deallocate all stale thread states. Even if this
+ executes Python code, we should be safe since it executes
+ in the current thread, not one of the stale threads. */
+ PyThreadState *p, *next;
+ for (p = list; p; p = next) {
+ next = p->next;
+ PyThreadState_Clear(p);
+ PyMem_RawFree(p);
+ }
+}
+
+
+PyThreadState *
+_PyThreadState_UncheckedGet(void)
+{
+ return _PyThreadState_GET();
+}
+
+
+PyThreadState *
+PyThreadState_Get(void)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ _Py_EnsureTstateNotNULL(tstate);
+ return tstate;
+}
+
+
+PyThreadState *
+_PyThreadState_Swap(struct _gilstate_runtime_state *gilstate, PyThreadState *newts)
+{
+ PyThreadState *oldts = _PyRuntimeGILState_GetThreadState(gilstate);
+
+ _PyRuntimeGILState_SetThreadState(gilstate, newts);
+ /* It should not be possible for more than one thread state
+ to be used for a thread. Check this the best we can in debug
+ builds.
+ */
+#if defined(Py_DEBUG)
+ if (newts) {
+ /* This can be called from PyEval_RestoreThread(). Similar
+ to it, we need to ensure errno doesn't change.
+ */
+ int err = errno;
+ PyThreadState *check = _PyGILState_GetThisThreadState(gilstate);
+ if (check && check->interp == newts->interp && check != newts)
+ Py_FatalError("Invalid thread state for this thread");
+ errno = err;
+ }
+#endif
+ return oldts;
+}
+
+PyThreadState *
+PyThreadState_Swap(PyThreadState *newts)
+{
+ return _PyThreadState_Swap(&_PyRuntime.gilstate, newts);
+}
+
+/* An extension mechanism to store arbitrary additional per-thread state.
+ PyThreadState_GetDict() returns a dictionary that can be used to hold such
+ state; the caller should pick a unique key and store its state there. If
+ PyThreadState_GetDict() returns NULL, an exception has *not* been raised
+ and the caller should assume no per-thread state is available. */
+
+PyObject *
+_PyThreadState_GetDict(PyThreadState *tstate)
+{
+ assert(tstate != NULL);
+ if (tstate->dict == NULL) {
+ tstate->dict = PyDict_New();
+ if (tstate->dict == NULL) {
+ _PyErr_Clear(tstate);
+ }
+ }
+ return tstate->dict;
+}
+
+
+PyObject *
+PyThreadState_GetDict(void)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (tstate == NULL) {
+ return NULL;
+ }
+ return _PyThreadState_GetDict(tstate);
+}
+
+
+PyInterpreterState *
+PyThreadState_GetInterpreter(PyThreadState *tstate)
+{
+ assert(tstate != NULL);
+ return tstate->interp;
+}
+
+
+PyFrameObject*
+PyThreadState_GetFrame(PyThreadState *tstate)
+{
+ assert(tstate != NULL);
+ PyFrameObject *frame = tstate->frame;
+ Py_XINCREF(frame);
+ return frame;
+}
+
+
+uint64_t
+PyThreadState_GetID(PyThreadState *tstate)
+{
+ assert(tstate != NULL);
+ return tstate->id;
+}
+
+
+/* Asynchronously raise an exception in a thread.
+ Requested by Just van Rossum and Alex Martelli.
+ To prevent naive misuse, you must write your own extension
+ to call this, or use ctypes. Must be called with the GIL held.
+ Returns the number of tstates modified (normally 1, but 0 if `id` didn't
+ match any known thread id). Can be called with exc=NULL to clear an
+ existing async exception. This raises no exceptions. */
+
+int
+PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc)
+{
+ _PyRuntimeState *runtime = &_PyRuntime;
+ PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp;
+
+ /* Although the GIL is held, a few C API functions can be called
+ * without the GIL held, and in particular some that create and
+ * destroy thread and interpreter states. Those can mutate the
+ * list of thread states we're traversing, so to prevent that we lock
+ * head_mutex for the duration.
+ */
+ HEAD_LOCK(runtime);
+ for (PyThreadState *tstate = interp->tstate_head; tstate != NULL; tstate = tstate->next) {
+ if (tstate->thread_id != id) {
+ continue;
+ }
+
+ /* Tricky: we need to decref the current value
+ * (if any) in tstate->async_exc, but that can in turn
+ * allow arbitrary Python code to run, including
+ * perhaps calls to this function. To prevent
+ * deadlock, we need to release head_mutex before
+ * the decref.
+ */
+ PyObject *old_exc = tstate->async_exc;
+ Py_XINCREF(exc);
+ tstate->async_exc = exc;
+ HEAD_UNLOCK(runtime);
+
+ Py_XDECREF(old_exc);
+ _PyEval_SignalAsyncExc(tstate);
+ return 1;
+ }
+ HEAD_UNLOCK(runtime);
+ return 0;
+}
+
+
+/* Routines for advanced debuggers, requested by David Beazley.
+ Don't use unless you know what you are doing! */
+
+PyInterpreterState *
+PyInterpreterState_Head(void)
+{
+ return _PyRuntime.interpreters.head;
+}
+
+PyInterpreterState *
+PyInterpreterState_Main(void)
+{
+ return _PyRuntime.interpreters.main;
+}
+
+PyInterpreterState *
+PyInterpreterState_Next(PyInterpreterState *interp) {
+ return interp->next;
+}
+
+PyThreadState *
+PyInterpreterState_ThreadHead(PyInterpreterState *interp) {
+ return interp->tstate_head;
+}
+
+PyThreadState *
+PyThreadState_Next(PyThreadState *tstate) {
+ return tstate->next;
+}
+
+/* The implementation of sys._current_frames(). This is intended to be
+ called with the GIL held, as it will be when called via
+ sys._current_frames(). It's possible it would work fine even without
+ the GIL held, but haven't thought enough about that.
+*/
+PyObject *
+_PyThread_CurrentFrames(void)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (_PySys_Audit(tstate, "sys._current_frames", NULL) < 0) {
+ return NULL;
+ }
+
+ PyObject *result = PyDict_New();
+ if (result == NULL) {
+ return NULL;
+ }
+
+ /* for i in all interpreters:
+ * for t in all of i's thread states:
+ * if t's frame isn't NULL, map t's id to its frame
+ * Because these lists can mutate even when the GIL is held, we
+ * need to grab head_mutex for the duration.
+ */
+ _PyRuntimeState *runtime = tstate->interp->runtime;
+ HEAD_LOCK(runtime);
+ PyInterpreterState *i;
+ for (i = runtime->interpreters.head; i != NULL; i = i->next) {
+ PyThreadState *t;
+ for (t = i->tstate_head; t != NULL; t = t->next) {
+ PyFrameObject *frame = t->frame;
+ if (frame == NULL) {
+ continue;
+ }
+ PyObject *id = PyLong_FromUnsignedLong(t->thread_id);
+ if (id == NULL) {
+ goto fail;
+ }
+ int stat = PyDict_SetItem(result, id, (PyObject *)frame);
+ Py_DECREF(id);
+ if (stat < 0) {
+ goto fail;
+ }
+ }
+ }
+ goto done;
+
+fail:
+ Py_CLEAR(result);
+
+done:
+ HEAD_UNLOCK(runtime);
+ return result;
+}
+
+/* Python "auto thread state" API. */
+
+/* Keep this as a static, as it is not reliable! It can only
+ ever be compared to the state for the *current* thread.
+ * If not equal, then it doesn't matter that the actual
+ value may change immediately after comparison, as it can't
+ possibly change to the current thread's state.
+ * If equal, then the current thread holds the lock, so the value can't
+ change until we yield the lock.
+*/
+static int
+PyThreadState_IsCurrent(PyThreadState *tstate)
+{
+ /* Must be the tstate for this thread */
+ struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate;
+ assert(_PyGILState_GetThisThreadState(gilstate) == tstate);
+ return tstate == _PyRuntimeGILState_GetThreadState(gilstate);
+}
+
+/* Internal initialization/finalization functions called by
+ Py_Initialize/Py_FinalizeEx
+*/
+PyStatus
+_PyGILState_Init(PyThreadState *tstate)
+{
+ if (!_Py_IsMainInterpreter(tstate)) {
+ /* Currently, PyGILState is shared by all interpreters. The main
+ * interpreter is responsible to initialize it. */
+ return _PyStatus_OK();
+ }
+
+ /* must init with valid states */
+ assert(tstate != NULL);
+ assert(tstate->interp != NULL);
+
+ struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate;
+
+ if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) {
+ return _PyStatus_NO_MEMORY();
+ }
+ gilstate->autoInterpreterState = tstate->interp;
+ assert(PyThread_tss_get(&gilstate->autoTSSkey) == NULL);
+ assert(tstate->gilstate_counter == 0);
+
+ _PyGILState_NoteThreadState(gilstate, tstate);
+ return _PyStatus_OK();
+}
+
+PyInterpreterState *
+_PyGILState_GetInterpreterStateUnsafe(void)
+{
+ return _PyRuntime.gilstate.autoInterpreterState;
+}
+
+void
+_PyGILState_Fini(PyThreadState *tstate)
+{
+ struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate;
+ PyThread_tss_delete(&gilstate->autoTSSkey);
+ gilstate->autoInterpreterState = NULL;
+}
+
+/* Reset the TSS key - called by PyOS_AfterFork_Child().
+ * This should not be necessary, but some - buggy - pthread implementations
+ * don't reset TSS upon fork(), see issue #10517.
+ */
+void
+_PyGILState_Reinit(_PyRuntimeState *runtime)
+{
+ struct _gilstate_runtime_state *gilstate = &runtime->gilstate;
+ PyThreadState *tstate = _PyGILState_GetThisThreadState(gilstate);
+
+ PyThread_tss_delete(&gilstate->autoTSSkey);
+ if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) {
+ Py_FatalError("Could not allocate TSS entry");
+ }
+
+ /* If the thread had an associated auto thread state, reassociate it with
+ * the new key. */
+ if (tstate &&
+ PyThread_tss_set(&gilstate->autoTSSkey, (void *)tstate) != 0)
+ {
+ Py_FatalError("Couldn't create autoTSSkey mapping");
+ }
+}
+
+/* When a thread state is created for a thread by some mechanism other than
+ PyGILState_Ensure, it's important that the GILState machinery knows about
+ it so it doesn't try to create another thread state for the thread (this is
+ a better fix for SF bug #1010677 than the first one attempted).
+*/
+static void
+_PyGILState_NoteThreadState(struct _gilstate_runtime_state *gilstate, PyThreadState* tstate)
+{
+ /* If autoTSSkey isn't initialized, this must be the very first
+ threadstate created in Py_Initialize(). Don't do anything for now
+ (we'll be back here when _PyGILState_Init is called). */
+ if (!gilstate->autoInterpreterState) {
+ return;
+ }
+
+ /* Stick the thread state for this thread in thread specific storage.
+
+ The only situation where you can legitimately have more than one
+ thread state for an OS level thread is when there are multiple
+ interpreters.
+
+ You shouldn't really be using the PyGILState_ APIs anyway (see issues
+ #10915 and #15751).
+
+ The first thread state created for that given OS level thread will
+ "win", which seems reasonable behaviour.
+ */
+ if (PyThread_tss_get(&gilstate->autoTSSkey) == NULL) {
+ if ((PyThread_tss_set(&gilstate->autoTSSkey, (void *)tstate)) != 0) {
+ Py_FatalError("Couldn't create autoTSSkey mapping");
+ }
+ }
+
+ /* PyGILState_Release must not try to delete this thread state. */
+ tstate->gilstate_counter = 1;
+}
+
+/* The public functions */
+static PyThreadState *
+_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate)
+{
+ if (gilstate->autoInterpreterState == NULL)
+ return NULL;
+ return (PyThreadState *)PyThread_tss_get(&gilstate->autoTSSkey);
+}
+
+PyThreadState *
+PyGILState_GetThisThreadState(void)
+{
+ return _PyGILState_GetThisThreadState(&_PyRuntime.gilstate);
+}
+
+int
+PyGILState_Check(void)
+{
+ struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate;
+ if (!gilstate->check_enabled) {
+ return 1;
+ }
+
+ if (!PyThread_tss_is_created(&gilstate->autoTSSkey)) {
+ return 1;
+ }
+
+ PyThreadState *tstate = _PyRuntimeGILState_GetThreadState(gilstate);
+ if (tstate == NULL) {
+ return 0;
+ }
+
+ return (tstate == _PyGILState_GetThisThreadState(gilstate));
+}
+
+PyGILState_STATE
+PyGILState_Ensure(void)
+{
+ _PyRuntimeState *runtime = &_PyRuntime;
+ struct _gilstate_runtime_state *gilstate = &runtime->gilstate;
+
+ /* Note that we do not auto-init Python here - apart from
+ potential races with 2 threads auto-initializing, pep-311
+ spells out other issues. Embedders are expected to have
+ called Py_Initialize(). */
+
+ /* Ensure that _PyEval_InitThreads() and _PyGILState_Init() have been
+ called by Py_Initialize() */
+ assert(_PyEval_ThreadsInitialized(runtime));
+ assert(gilstate->autoInterpreterState);
+
+ PyThreadState *tcur = (PyThreadState *)PyThread_tss_get(&gilstate->autoTSSkey);
+ int current;
+ if (tcur == NULL) {
+ /* Create a new Python thread state for this thread */
+ tcur = PyThreadState_New(gilstate->autoInterpreterState);
+ if (tcur == NULL) {
+ Py_FatalError("Couldn't create thread-state for new thread");
+ }
+
+ /* This is our thread state! We'll need to delete it in the
+ matching call to PyGILState_Release(). */
+ tcur->gilstate_counter = 0;
+ current = 0; /* new thread state is never current */
+ }
+ else {
+ current = PyThreadState_IsCurrent(tcur);
+ }
+
+ if (current == 0) {
+ PyEval_RestoreThread(tcur);
+ }
+
+ /* Update our counter in the thread-state - no need for locks:
+ - tcur will remain valid as we hold the GIL.
+ - the counter is safe as we are the only thread "allowed"
+ to modify this value
+ */
+ ++tcur->gilstate_counter;
+
+ return current ? PyGILState_LOCKED : PyGILState_UNLOCKED;
+}
+
+void
+PyGILState_Release(PyGILState_STATE oldstate)
+{
+ _PyRuntimeState *runtime = &_PyRuntime;
+ PyThreadState *tstate = PyThread_tss_get(&runtime->gilstate.autoTSSkey);
+ if (tstate == NULL) {
+ Py_FatalError("auto-releasing thread-state, "
+ "but no thread-state for this thread");
+ }
+
+ /* We must hold the GIL and have our thread state current */
+ /* XXX - remove the check - the assert should be fine,
+ but while this is very new (April 2003), the extra check
+ by release-only users can't hurt.
+ */
+ if (!PyThreadState_IsCurrent(tstate)) {
+ _Py_FatalErrorFormat(__func__,
+ "thread state %p must be current when releasing",
+ tstate);
+ }
+ assert(PyThreadState_IsCurrent(tstate));
+ --tstate->gilstate_counter;
+ assert(tstate->gilstate_counter >= 0); /* illegal counter value */
+
+ /* If we're going to destroy this thread-state, we must
+ * clear it while the GIL is held, as destructors may run.
+ */
+ if (tstate->gilstate_counter == 0) {
+ /* can't have been locked when we created it */
+ assert(oldstate == PyGILState_UNLOCKED);
+ PyThreadState_Clear(tstate);
+ /* Delete the thread-state. Note this releases the GIL too!
+ * It's vital that the GIL be held here, to avoid shutdown
+ * races; see bugs 225673 and 1061968 (that nasty bug has a
+ * habit of coming back).
+ */
+ assert(_PyRuntimeGILState_GetThreadState(&runtime->gilstate) == tstate);
+ _PyThreadState_DeleteCurrent(tstate);
+ }
+ /* Release the lock if necessary */
+ else if (oldstate == PyGILState_UNLOCKED)
+ PyEval_SaveThread();
+}
+
+
+/**************************/
+/* cross-interpreter data */
+/**************************/
+
+/* cross-interpreter data */
+
+crossinterpdatafunc _PyCrossInterpreterData_Lookup(PyObject *);
+
+/* This is a separate func from _PyCrossInterpreterData_Lookup in order
+ to keep the registry code separate. */
+static crossinterpdatafunc
+_lookup_getdata(PyObject *obj)
+{
+ crossinterpdatafunc getdata = _PyCrossInterpreterData_Lookup(obj);
+ if (getdata == NULL && PyErr_Occurred() == 0)
+ PyErr_Format(PyExc_ValueError,
+ "%S does not support cross-interpreter data", obj);
+ return getdata;
+}
+
+int
+_PyObject_CheckCrossInterpreterData(PyObject *obj)
+{
+ crossinterpdatafunc getdata = _lookup_getdata(obj);
+ if (getdata == NULL) {
+ return -1;
+ }
+ return 0;
+}
+
+static int
+_check_xidata(PyThreadState *tstate, _PyCrossInterpreterData *data)
+{
+ // data->data can be anything, including NULL, so we don't check it.
+
+ // data->obj may be NULL, so we don't check it.
+
+ if (data->interp < 0) {
+ _PyErr_SetString(tstate, PyExc_SystemError, "missing interp");
+ return -1;
+ }
+
+ if (data->new_object == NULL) {
+ _PyErr_SetString(tstate, PyExc_SystemError, "missing new_object func");
+ return -1;
+ }
+
+ // data->free may be NULL, so we don't check it.
+
+ return 0;
+}
+
+int
+_PyObject_GetCrossInterpreterData(PyObject *obj, _PyCrossInterpreterData *data)
+{
+ // PyThreadState_Get() aborts if tstate is NULL.
+ PyThreadState *tstate = PyThreadState_Get();
+ PyInterpreterState *interp = tstate->interp;
+
+ // Reset data before re-populating.
+ *data = (_PyCrossInterpreterData){0};
+ data->free = PyMem_RawFree; // Set a default that may be overridden.
+
+ // Call the "getdata" func for the object.
+ Py_INCREF(obj);
+ crossinterpdatafunc getdata = _lookup_getdata(obj);
+ if (getdata == NULL) {
+ Py_DECREF(obj);
+ return -1;
+ }
+ int res = getdata(obj, data);
+ Py_DECREF(obj);
+ if (res != 0) {
+ return -1;
+ }
+
+ // Fill in the blanks and validate the result.
+ data->interp = interp->id;
+ if (_check_xidata(tstate, data) != 0) {
+ _PyCrossInterpreterData_Release(data);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void
+_release_xidata(void *arg)
+{
+ _PyCrossInterpreterData *data = (_PyCrossInterpreterData *)arg;
+ if (data->free != NULL) {
+ data->free(data->data);
+ }
+ Py_XDECREF(data->obj);
+}
+
+static void
+_call_in_interpreter(struct _gilstate_runtime_state *gilstate,
+ PyInterpreterState *interp,
+ void (*func)(void *), void *arg)
+{
+ /* We would use Py_AddPendingCall() if it weren't specific to the
+ * main interpreter (see bpo-33608). In the meantime we take a
+ * naive approach.
+ */
+ PyThreadState *save_tstate = NULL;
+ if (interp != _PyRuntimeGILState_GetThreadState(gilstate)->interp) {
+ // XXX Using the "head" thread isn't strictly correct.
+ PyThreadState *tstate = PyInterpreterState_ThreadHead(interp);
+ // XXX Possible GILState issues?
+ save_tstate = _PyThreadState_Swap(gilstate, tstate);
+ }
+
+ func(arg);
+
+ // Switch back.
+ if (save_tstate != NULL) {
+ _PyThreadState_Swap(gilstate, save_tstate);
+ }
+}
+
+void
+_PyCrossInterpreterData_Release(_PyCrossInterpreterData *data)
+{
+ if (data->data == NULL && data->obj == NULL) {
+ // Nothing to release!
+ return;
+ }
+
+ // Switch to the original interpreter.
+ PyInterpreterState *interp = _PyInterpreterState_LookUpID(data->interp);
+ if (interp == NULL) {
+ // The interpreter was already destroyed.
+ if (data->free != NULL) {
+ // XXX Someone leaked some memory...
+ }
+ return;
+ }
+
+ // "Release" the data and/or the object.
+ struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate;
+ _call_in_interpreter(gilstate, interp, _release_xidata, data);
+}
+
+PyObject *
+_PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *data)
+{
+ return data->new_object(data);
+}
+
+/* registry of {type -> crossinterpdatafunc} */
+
+/* For now we use a global registry of shareable classes. An
+ alternative would be to add a tp_* slot for a class's
+ crossinterpdatafunc. It would be simpler and more efficient. */
+
+static int
+_register_xidata(struct _xidregistry *xidregistry, PyTypeObject *cls,
+ crossinterpdatafunc getdata)
+{
+ // Note that we effectively replace already registered classes
+ // rather than failing.
+ struct _xidregitem *newhead = PyMem_RawMalloc(sizeof(struct _xidregitem));
+ if (newhead == NULL)
+ return -1;
+ newhead->cls = cls;
+ newhead->getdata = getdata;
+ newhead->next = xidregistry->head;
+ xidregistry->head = newhead;
+ return 0;
+}
+
+static void _register_builtins_for_crossinterpreter_data(struct _xidregistry *xidregistry);
+
+int
+_PyCrossInterpreterData_RegisterClass(PyTypeObject *cls,
+ crossinterpdatafunc getdata)
+{
+ if (!PyType_Check(cls)) {
+ PyErr_Format(PyExc_ValueError, "only classes may be registered");
+ return -1;
+ }
+ if (getdata == NULL) {
+ PyErr_Format(PyExc_ValueError, "missing 'getdata' func");
+ return -1;
+ }
+
+ // Make sure the class isn't ever deallocated.
+ Py_INCREF((PyObject *)cls);
+
+ struct _xidregistry *xidregistry = &_PyRuntime.xidregistry ;
+ PyThread_acquire_lock(xidregistry->mutex, WAIT_LOCK);
+ if (xidregistry->head == NULL) {
+ _register_builtins_for_crossinterpreter_data(xidregistry);
+ }
+ int res = _register_xidata(xidregistry, cls, getdata);
+ PyThread_release_lock(xidregistry->mutex);
+ return res;
+}
+
+/* Cross-interpreter objects are looked up by exact match on the class.
+ We can reassess this policy when we move from a global registry to a
+ tp_* slot. */
+
+crossinterpdatafunc
+_PyCrossInterpreterData_Lookup(PyObject *obj)
+{
+ struct _xidregistry *xidregistry = &_PyRuntime.xidregistry ;
+ PyObject *cls = PyObject_Type(obj);
+ crossinterpdatafunc getdata = NULL;
+ PyThread_acquire_lock(xidregistry->mutex, WAIT_LOCK);
+ struct _xidregitem *cur = xidregistry->head;
+ if (cur == NULL) {
+ _register_builtins_for_crossinterpreter_data(xidregistry);
+ cur = xidregistry->head;
+ }
+ for(; cur != NULL; cur = cur->next) {
+ if (cur->cls == (PyTypeObject *)cls) {
+ getdata = cur->getdata;
+ break;
+ }
+ }
+ Py_DECREF(cls);
+ PyThread_release_lock(xidregistry->mutex);
+ return getdata;
+}
+
+/* cross-interpreter data for builtin types */
+
+struct _shared_bytes_data {
+ char *bytes;
+ Py_ssize_t len;
+};
+
+static PyObject *
+_new_bytes_object(_PyCrossInterpreterData *data)
+{
+ struct _shared_bytes_data *shared = (struct _shared_bytes_data *)(data->data);
+ return PyBytes_FromStringAndSize(shared->bytes, shared->len);
+}
+
+static int
+_bytes_shared(PyObject *obj, _PyCrossInterpreterData *data)
+{
+ struct _shared_bytes_data *shared = PyMem_NEW(struct _shared_bytes_data, 1);
+ if (PyBytes_AsStringAndSize(obj, &shared->bytes, &shared->len) < 0) {
+ return -1;
+ }
+ data->data = (void *)shared;
+ Py_INCREF(obj);
+ data->obj = obj; // Will be "released" (decref'ed) when data released.
+ data->new_object = _new_bytes_object;
+ data->free = PyMem_Free;
+ return 0;
+}
+
+struct _shared_str_data {
+ int kind;
+ const void *buffer;
+ Py_ssize_t len;
+};
+
+static PyObject *
+_new_str_object(_PyCrossInterpreterData *data)
+{
+ struct _shared_str_data *shared = (struct _shared_str_data *)(data->data);
+ return PyUnicode_FromKindAndData(shared->kind, shared->buffer, shared->len);
+}
+
+static int
+_str_shared(PyObject *obj, _PyCrossInterpreterData *data)
+{
+ struct _shared_str_data *shared = PyMem_NEW(struct _shared_str_data, 1);
+ shared->kind = PyUnicode_KIND(obj);
+ shared->buffer = PyUnicode_DATA(obj);
+ shared->len = PyUnicode_GET_LENGTH(obj);
+ data->data = (void *)shared;
+ Py_INCREF(obj);
+ data->obj = obj; // Will be "released" (decref'ed) when data released.
+ data->new_object = _new_str_object;
+ data->free = PyMem_Free;
+ return 0;
+}
+
+static PyObject *
+_new_long_object(_PyCrossInterpreterData *data)
+{
+ return PyLong_FromSsize_t((Py_ssize_t)(data->data));
+}
+
+static int
+_long_shared(PyObject *obj, _PyCrossInterpreterData *data)
+{
+ /* Note that this means the size of shareable ints is bounded by
+ * sys.maxsize. Hence on 32-bit architectures that is half the
+ * size of maximum shareable ints on 64-bit.
+ */
+ Py_ssize_t value = PyLong_AsSsize_t(obj);
+ if (value == -1 && PyErr_Occurred()) {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
+ PyErr_SetString(PyExc_OverflowError, "try sending as bytes");
+ }
+ return -1;
+ }
+ data->data = (void *)value;
+ data->obj = NULL;
+ data->new_object = _new_long_object;
+ data->free = NULL;
+ return 0;
+}
+
+static PyObject *
+_new_none_object(_PyCrossInterpreterData *data)
+{
+ // XXX Singleton refcounts are problematic across interpreters...
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static int
+_none_shared(PyObject *obj, _PyCrossInterpreterData *data)
+{
+ data->data = NULL;
+ // data->obj remains NULL
+ data->new_object = _new_none_object;
+ data->free = NULL; // There is nothing to free.
+ return 0;
+}
+
+static void
+_register_builtins_for_crossinterpreter_data(struct _xidregistry *xidregistry)
+{
+ // None
+ if (_register_xidata(xidregistry, (PyTypeObject *)PyObject_Type(Py_None), _none_shared) != 0) {
+ Py_FatalError("could not register None for cross-interpreter sharing");
+ }
+
+ // int
+ if (_register_xidata(xidregistry, &PyLong_Type, _long_shared) != 0) {
+ Py_FatalError("could not register int for cross-interpreter sharing");
+ }
+
+ // bytes
+ if (_register_xidata(xidregistry, &PyBytes_Type, _bytes_shared) != 0) {
+ Py_FatalError("could not register bytes for cross-interpreter sharing");
+ }
+
+ // str
+ if (_register_xidata(xidregistry, &PyUnicode_Type, _str_shared) != 0) {
+ Py_FatalError("could not register str for cross-interpreter sharing");
+ }
+}
+
+
+_PyFrameEvalFunction
+_PyInterpreterState_GetEvalFrameFunc(PyInterpreterState *interp)
+{
+ return interp->eval_frame;
+}
+
+
+void
+_PyInterpreterState_SetEvalFrameFunc(PyInterpreterState *interp,
+ _PyFrameEvalFunction eval_frame)
+{
+ interp->eval_frame = eval_frame;
+}
+
+
+const PyConfig*
+_PyInterpreterState_GetConfig(PyInterpreterState *interp)
+{
+ return &interp->config;
+}
+
+
+PyStatus
+_PyInterpreterState_SetConfig(PyInterpreterState *interp,
+ const PyConfig *config)
+{
+ return _PyConfig_Copy(&interp->config, config);
+}
+
+
+const PyConfig*
+_Py_GetConfig(void)
+{
+ assert(PyGILState_Check());
+ PyThreadState *tstate = _PyThreadState_GET();
+ return _PyInterpreterState_GetConfig(tstate->interp);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/contrib/tools/python3/src/Python/pystrcmp.c b/contrib/tools/python3/src/Python/pystrcmp.c
new file mode 100644
index 00000000000..9224ce4c706
--- /dev/null
+++ b/contrib/tools/python3/src/Python/pystrcmp.c
@@ -0,0 +1,30 @@
+/* Cross platform case insensitive string compare functions
+ */
+
+#include "Python.h"
+
+int
+PyOS_mystrnicmp(const char *s1, const char *s2, Py_ssize_t size)
+{
+ const unsigned char *p1, *p2;
+ if (size == 0)
+ return 0;
+ p1 = (const unsigned char *)s1;
+ p2 = (const unsigned char *)s2;
+ for (; (--size > 0) && *p1 && *p2 && (tolower(*p1) == tolower(*p2));
+ p1++, p2++) {
+ ;
+ }
+ return tolower(*p1) - tolower(*p2);
+}
+
+int
+PyOS_mystricmp(const char *s1, const char *s2)
+{
+ const unsigned char *p1 = (const unsigned char *)s1;
+ const unsigned char *p2 = (const unsigned char *)s2;
+ for (; *p1 && *p2 && (tolower(*p1) == tolower(*p2)); p1++, p2++) {
+ ;
+ }
+ return (tolower(*p1) - tolower(*p2));
+}
diff --git a/contrib/tools/python3/src/Python/pystrhex.c b/contrib/tools/python3/src/Python/pystrhex.c
new file mode 100644
index 00000000000..b74e57ad913
--- /dev/null
+++ b/contrib/tools/python3/src/Python/pystrhex.c
@@ -0,0 +1,172 @@
+/* bytes to hex implementation */
+
+#include "Python.h"
+
+#include "pystrhex.h"
+
+static PyObject *_Py_strhex_impl(const char* argbuf, const Py_ssize_t arglen,
+ const PyObject* sep, int bytes_per_sep_group,
+ const int return_bytes)
+{
+ assert(arglen >= 0);
+
+ Py_UCS1 sep_char = 0;
+ if (sep) {
+ Py_ssize_t seplen = PyObject_Length((PyObject*)sep);
+ if (seplen < 0) {
+ return NULL;
+ }
+ if (seplen != 1) {
+ PyErr_SetString(PyExc_ValueError, "sep must be length 1.");
+ return NULL;
+ }
+ if (PyUnicode_Check(sep)) {
+ if (PyUnicode_READY(sep))
+ return NULL;
+ if (PyUnicode_KIND(sep) != PyUnicode_1BYTE_KIND) {
+ PyErr_SetString(PyExc_ValueError, "sep must be ASCII.");
+ return NULL;
+ }
+ sep_char = PyUnicode_READ_CHAR(sep, 0);
+ }
+ else if (PyBytes_Check(sep)) {
+ sep_char = PyBytes_AS_STRING(sep)[0];
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError, "sep must be str or bytes.");
+ return NULL;
+ }
+ if (sep_char > 127 && !return_bytes) {
+ PyErr_SetString(PyExc_ValueError, "sep must be ASCII.");
+ return NULL;
+ }
+ }
+ else {
+ bytes_per_sep_group = 0;
+ }
+
+ unsigned int abs_bytes_per_sep = abs(bytes_per_sep_group);
+ Py_ssize_t resultlen = 0;
+ if (bytes_per_sep_group && arglen > 0) {
+ /* How many sep characters we'll be inserting. */
+ resultlen = (arglen - 1) / abs_bytes_per_sep;
+ }
+ /* Bounds checking for our Py_ssize_t indices. */
+ if (arglen >= PY_SSIZE_T_MAX / 2 - resultlen) {
+ return PyErr_NoMemory();
+ }
+ resultlen += arglen * 2;
+
+ if ((size_t)abs_bytes_per_sep >= (size_t)arglen) {
+ bytes_per_sep_group = 0;
+ abs_bytes_per_sep = 0;
+ }
+
+ PyObject *retval;
+ Py_UCS1 *retbuf;
+ if (return_bytes) {
+ /* If _PyBytes_FromSize() were public we could avoid malloc+copy. */
+ retval = PyBytes_FromStringAndSize(NULL, resultlen);
+ if (!retval) {
+ return NULL;
+ }
+ retbuf = (Py_UCS1 *)PyBytes_AS_STRING(retval);
+ }
+ else {
+ retval = PyUnicode_New(resultlen, 127);
+ if (!retval) {
+ return NULL;
+ }
+ retbuf = PyUnicode_1BYTE_DATA(retval);
+ }
+
+ /* Hexlify */
+ Py_ssize_t i, j;
+ 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];
+ }
+ assert(j == resultlen);
+ }
+ else {
+ /* The number of complete chunk+sep periods */
+ Py_ssize_t chunks = (arglen - 1) / abs_bytes_per_sep;
+ Py_ssize_t chunk;
+ unsigned int k;
+
+ if (bytes_per_sep_group < 0) {
+ i = j = 0;
+ for (chunk = 0; chunk < chunks; chunk++) {
+ for (k = 0; k < abs_bytes_per_sep; k++) {
+ c = argbuf[i++];
+ retbuf[j++] = Py_hexdigits[c >> 4];
+ retbuf[j++] = Py_hexdigits[c & 0x0f];
+ }
+ retbuf[j++] = sep_char;
+ }
+ while (i < arglen) {
+ c = argbuf[i++];
+ retbuf[j++] = Py_hexdigits[c >> 4];
+ retbuf[j++] = Py_hexdigits[c & 0x0f];
+ }
+ assert(j == resultlen);
+ }
+ else {
+ i = arglen - 1;
+ j = resultlen - 1;
+ for (chunk = 0; chunk < chunks; chunk++) {
+ for (k = 0; k < abs_bytes_per_sep; k++) {
+ c = argbuf[i--];
+ retbuf[j--] = Py_hexdigits[c & 0x0f];
+ retbuf[j--] = Py_hexdigits[c >> 4];
+ }
+ retbuf[j--] = sep_char;
+ }
+ while (i >= 0) {
+ c = argbuf[i--];
+ retbuf[j--] = Py_hexdigits[c & 0x0f];
+ retbuf[j--] = Py_hexdigits[c >> 4];
+ }
+ assert(j == -1);
+ }
+ }
+
+#ifdef Py_DEBUG
+ if (!return_bytes) {
+ assert(_PyUnicode_CheckConsistency(retval, 1));
+ }
+#endif
+
+ return retval;
+}
+
+PyObject * _Py_strhex(const char* argbuf, const Py_ssize_t arglen)
+{
+ return _Py_strhex_impl(argbuf, arglen, NULL, 0, 0);
+}
+
+/* Same as above but returns a bytes() instead of str() to avoid the
+ * need to decode the str() when bytes are needed. */
+PyObject * _Py_strhex_bytes(const char* argbuf, const Py_ssize_t arglen)
+{
+ return _Py_strhex_impl(argbuf, arglen, NULL, 0, 1);
+}
+
+/* These variants include support for a separator between every N bytes: */
+
+PyObject * _Py_strhex_with_sep(const char* argbuf, const Py_ssize_t arglen, const PyObject* sep, const int bytes_per_group)
+{
+ return _Py_strhex_impl(argbuf, arglen, sep, bytes_per_group, 0);
+}
+
+/* Same as above but returns a bytes() instead of str() to avoid the
+ * need to decode the str() when bytes are needed. */
+PyObject * _Py_strhex_bytes_with_sep(const char* argbuf, const Py_ssize_t arglen, const PyObject* sep, const int bytes_per_group)
+{
+ return _Py_strhex_impl(argbuf, arglen, sep, bytes_per_group, 1);
+}
diff --git a/contrib/tools/python3/src/Python/pystrtod.c b/contrib/tools/python3/src/Python/pystrtod.c
new file mode 100644
index 00000000000..1c8202c7761
--- /dev/null
+++ b/contrib/tools/python3/src/Python/pystrtod.c
@@ -0,0 +1,1307 @@
+/* -*- Mode: C; c-file-style: "python" -*- */
+
+#include <Python.h>
+#include "pycore_dtoa.h"
+#include <locale.h>
+
+/* Case-insensitive string match used for nan and inf detection; t should be
+ lower-case. Returns 1 for a successful match, 0 otherwise. */
+
+static int
+case_insensitive_match(const char *s, const char *t)
+{
+ while(*t && Py_TOLOWER(*s) == *t) {
+ s++;
+ t++;
+ }
+ return *t ? 0 : 1;
+}
+
+/* _Py_parse_inf_or_nan: Attempt to parse a string of the form "nan", "inf" or
+ "infinity", with an optional leading sign of "+" or "-". On success,
+ return the NaN or Infinity as a double and set *endptr to point just beyond
+ the successfully parsed portion of the string. On failure, return -1.0 and
+ set *endptr to point to the start of the string. */
+
+#ifndef PY_NO_SHORT_FLOAT_REPR
+
+double
+_Py_parse_inf_or_nan(const char *p, char **endptr)
+{
+ double retval;
+ const char *s;
+ int negate = 0;
+
+ s = p;
+ if (*s == '-') {
+ negate = 1;
+ s++;
+ }
+ else if (*s == '+') {
+ s++;
+ }
+ if (case_insensitive_match(s, "inf")) {
+ s += 3;
+ if (case_insensitive_match(s, "inity"))
+ s += 5;
+ retval = _Py_dg_infinity(negate);
+ }
+ else if (case_insensitive_match(s, "nan")) {
+ s += 3;
+ retval = _Py_dg_stdnan(negate);
+ }
+ else {
+ s = p;
+ retval = -1.0;
+ }
+ *endptr = (char *)s;
+ return retval;
+}
+
+#else
+
+double
+_Py_parse_inf_or_nan(const char *p, char **endptr)
+{
+ double retval;
+ const char *s;
+ int negate = 0;
+
+ s = p;
+ if (*s == '-') {
+ negate = 1;
+ s++;
+ }
+ else if (*s == '+') {
+ s++;
+ }
+ if (case_insensitive_match(s, "inf")) {
+ s += 3;
+ if (case_insensitive_match(s, "inity"))
+ s += 5;
+ retval = negate ? -Py_HUGE_VAL : Py_HUGE_VAL;
+ }
+#ifdef Py_NAN
+ else if (case_insensitive_match(s, "nan")) {
+ s += 3;
+ retval = negate ? -Py_NAN : Py_NAN;
+ }
+#endif
+ else {
+ s = p;
+ retval = -1.0;
+ }
+ *endptr = (char *)s;
+ return retval;
+}
+
+#endif
+
+/**
+ * _PyOS_ascii_strtod:
+ * @nptr: the string to convert to a numeric value.
+ * @endptr: if non-%NULL, it returns the character after
+ * the last character used in the conversion.
+ *
+ * Converts a string to a #gdouble value.
+ * This function behaves like the standard strtod() function
+ * does in the C locale. It does this without actually
+ * changing the current locale, since that would not be
+ * thread-safe.
+ *
+ * This function is typically used when reading configuration
+ * files or other non-user input that should be locale independent.
+ * To handle input from the user you should normally use the
+ * locale-sensitive system strtod() function.
+ *
+ * If the correct value would cause overflow, plus or minus %HUGE_VAL
+ * is returned (according to the sign of the value), and %ERANGE is
+ * stored in %errno. If the correct value would cause underflow,
+ * zero is returned and %ERANGE is stored in %errno.
+ * If memory allocation fails, %ENOMEM is stored in %errno.
+ *
+ * This function resets %errno before calling strtod() so that
+ * you can reliably detect overflow and underflow.
+ *
+ * Return value: the #gdouble value.
+ **/
+
+#ifndef PY_NO_SHORT_FLOAT_REPR
+
+static double
+_PyOS_ascii_strtod(const char *nptr, char **endptr)
+{
+ double result;
+ _Py_SET_53BIT_PRECISION_HEADER;
+
+ assert(nptr != NULL);
+ /* Set errno to zero, so that we can distinguish zero results
+ and underflows */
+ errno = 0;
+
+ _Py_SET_53BIT_PRECISION_START;
+ result = _Py_dg_strtod(nptr, endptr);
+ _Py_SET_53BIT_PRECISION_END;
+
+ if (*endptr == nptr)
+ /* string might represent an inf or nan */
+ result = _Py_parse_inf_or_nan(nptr, endptr);
+
+ return result;
+
+}
+
+#else
+
+/*
+ Use system strtod; since strtod is locale aware, we may
+ have to first fix the decimal separator.
+
+ Note that unlike _Py_dg_strtod, the system strtod may not always give
+ correctly rounded results.
+*/
+
+static double
+_PyOS_ascii_strtod(const char *nptr, char **endptr)
+{
+ char *fail_pos;
+ double val;
+ struct lconv *locale_data;
+ const char *decimal_point;
+ size_t decimal_point_len;
+ const char *p, *decimal_point_pos;
+ const char *end = NULL; /* Silence gcc */
+ const char *digits_pos = NULL;
+ int negate = 0;
+
+ assert(nptr != NULL);
+
+ fail_pos = NULL;
+
+ locale_data = localeconv();
+ decimal_point = locale_data->decimal_point;
+ decimal_point_len = strlen(decimal_point);
+
+ assert(decimal_point_len != 0);
+
+ decimal_point_pos = NULL;
+
+ /* Parse infinities and nans */
+ val = _Py_parse_inf_or_nan(nptr, endptr);
+ if (*endptr != nptr)
+ return val;
+
+ /* Set errno to zero, so that we can distinguish zero results
+ and underflows */
+ errno = 0;
+
+ /* We process the optional sign manually, then pass the remainder to
+ the system strtod. This ensures that the result of an underflow
+ has the correct sign. (bug #1725) */
+ p = nptr;
+ /* Process leading sign, if present */
+ if (*p == '-') {
+ negate = 1;
+ p++;
+ }
+ else if (*p == '+') {
+ p++;
+ }
+
+ /* Some platform strtods accept hex floats; Python shouldn't (at the
+ moment), so we check explicitly for strings starting with '0x'. */
+ if (*p == '0' && (*(p+1) == 'x' || *(p+1) == 'X'))
+ goto invalid_string;
+
+ /* Check that what's left begins with a digit or decimal point */
+ if (!Py_ISDIGIT(*p) && *p != '.')
+ goto invalid_string;
+
+ digits_pos = p;
+ if (decimal_point[0] != '.' ||
+ decimal_point[1] != 0)
+ {
+ /* Look for a '.' in the input; if present, it'll need to be
+ swapped for the current locale's decimal point before we
+ call strtod. On the other hand, if we find the current
+ locale's decimal point then the input is invalid. */
+ while (Py_ISDIGIT(*p))
+ p++;
+
+ if (*p == '.')
+ {
+ decimal_point_pos = p++;
+
+ /* locate end of number */
+ while (Py_ISDIGIT(*p))
+ p++;
+
+ if (*p == 'e' || *p == 'E')
+ p++;
+ if (*p == '+' || *p == '-')
+ p++;
+ while (Py_ISDIGIT(*p))
+ p++;
+ end = p;
+ }
+ else if (strncmp(p, decimal_point, decimal_point_len) == 0)
+ /* Python bug #1417699 */
+ goto invalid_string;
+ /* For the other cases, we need not convert the decimal
+ point */
+ }
+
+ if (decimal_point_pos) {
+ char *copy, *c;
+ /* Create a copy of the input, with the '.' converted to the
+ locale-specific decimal point */
+ copy = (char *)PyMem_MALLOC(end - digits_pos +
+ 1 + decimal_point_len);
+ if (copy == NULL) {
+ *endptr = (char *)nptr;
+ errno = ENOMEM;
+ return val;
+ }
+
+ c = copy;
+ memcpy(c, digits_pos, decimal_point_pos - digits_pos);
+ c += decimal_point_pos - digits_pos;
+ memcpy(c, decimal_point, decimal_point_len);
+ c += decimal_point_len;
+ memcpy(c, decimal_point_pos + 1,
+ end - (decimal_point_pos + 1));
+ c += end - (decimal_point_pos + 1);
+ *c = 0;
+
+ val = strtod(copy, &fail_pos);
+
+ if (fail_pos)
+ {
+ if (fail_pos > decimal_point_pos)
+ fail_pos = (char *)digits_pos +
+ (fail_pos - copy) -
+ (decimal_point_len - 1);
+ else
+ fail_pos = (char *)digits_pos +
+ (fail_pos - copy);
+ }
+
+ PyMem_FREE(copy);
+
+ }
+ else {
+ val = strtod(digits_pos, &fail_pos);
+ }
+
+ if (fail_pos == digits_pos)
+ goto invalid_string;
+
+ if (negate && fail_pos != nptr)
+ val = -val;
+ *endptr = fail_pos;
+
+ return val;
+
+ invalid_string:
+ *endptr = (char*)nptr;
+ errno = EINVAL;
+ return -1.0;
+}
+
+#endif
+
+/* PyOS_string_to_double converts a null-terminated byte string s (interpreted
+ as a string of ASCII characters) to a float. The string should not have
+ leading or trailing whitespace. The conversion is independent of the
+ current locale.
+
+ If endptr is NULL, try to convert the whole string. Raise ValueError and
+ return -1.0 if the string is not a valid representation of a floating-point
+ number.
+
+ If endptr is non-NULL, try to convert as much of the string as possible.
+ If no initial segment of the string is the valid representation of a
+ floating-point number then *endptr is set to point to the beginning of the
+ string, -1.0 is returned and again ValueError is raised.
+
+ On overflow (e.g., when trying to convert '1e500' on an IEEE 754 machine),
+ if overflow_exception is NULL then +-Py_HUGE_VAL is returned, and no Python
+ exception is raised. Otherwise, overflow_exception should point to
+ a Python exception, this exception will be raised, -1.0 will be returned,
+ and *endptr will point just past the end of the converted value.
+
+ If any other failure occurs (for example lack of memory), -1.0 is returned
+ and the appropriate Python exception will have been set.
+*/
+
+double
+PyOS_string_to_double(const char *s,
+ char **endptr,
+ PyObject *overflow_exception)
+{
+ double x, result=-1.0;
+ char *fail_pos;
+
+ errno = 0;
+ x = _PyOS_ascii_strtod(s, &fail_pos);
+
+ if (errno == ENOMEM) {
+ PyErr_NoMemory();
+ fail_pos = (char *)s;
+ }
+ else if (!endptr && (fail_pos == s || *fail_pos != '\0'))
+ PyErr_Format(PyExc_ValueError,
+ "could not convert string to float: "
+ "'%.200s'", s);
+ else if (fail_pos == s)
+ PyErr_Format(PyExc_ValueError,
+ "could not convert string to float: "
+ "'%.200s'", s);
+ else if (errno == ERANGE && fabs(x) >= 1.0 && overflow_exception)
+ PyErr_Format(overflow_exception,
+ "value too large to convert to float: "
+ "'%.200s'", s);
+ else
+ result = x;
+
+ if (endptr != NULL)
+ *endptr = fail_pos;
+ return result;
+}
+
+/* Remove underscores that follow the underscore placement rule from
+ the string and then call the `innerfunc` function on the result.
+ It should return a new object or NULL on exception.
+
+ `what` is used for the error message emitted when underscores are detected
+ that don't follow the rule. `arg` is an opaque pointer passed to the inner
+ function.
+
+ This is used to implement underscore-agnostic conversion for floats
+ and complex numbers.
+*/
+PyObject *
+_Py_string_to_number_with_underscores(
+ const char *s, Py_ssize_t orig_len, const char *what, PyObject *obj, void *arg,
+ PyObject *(*innerfunc)(const char *, Py_ssize_t, void *))
+{
+ char prev;
+ const char *p, *last;
+ char *dup, *end;
+ PyObject *result;
+
+ assert(s[orig_len] == '\0');
+
+ if (strchr(s, '_') == NULL) {
+ return innerfunc(s, orig_len, arg);
+ }
+
+ dup = PyMem_Malloc(orig_len + 1);
+ if (dup == NULL) {
+ return PyErr_NoMemory();
+ }
+ end = dup;
+ prev = '\0';
+ last = s + orig_len;
+ for (p = s; *p; p++) {
+ if (*p == '_') {
+ /* Underscores are only allowed after digits. */
+ if (!(prev >= '0' && prev <= '9')) {
+ goto error;
+ }
+ }
+ else {
+ *end++ = *p;
+ /* Underscores are only allowed before digits. */
+ if (prev == '_' && !(*p >= '0' && *p <= '9')) {
+ goto error;
+ }
+ }
+ prev = *p;
+ }
+ /* Underscores are not allowed at the end. */
+ if (prev == '_') {
+ goto error;
+ }
+ /* No embedded NULs allowed. */
+ if (p != last) {
+ goto error;
+ }
+ *end = '\0';
+ result = innerfunc(dup, end - dup, arg);
+ PyMem_Free(dup);
+ return result;
+
+ error:
+ PyMem_Free(dup);
+ PyErr_Format(PyExc_ValueError,
+ "could not convert string to %s: "
+ "%R", what, obj);
+ return NULL;
+}
+
+#ifdef PY_NO_SHORT_FLOAT_REPR
+
+/* Given a string that may have a decimal point in the current
+ locale, change it back to a dot. Since the string cannot get
+ longer, no need for a maximum buffer size parameter. */
+Py_LOCAL_INLINE(void)
+change_decimal_from_locale_to_dot(char* buffer)
+{
+ struct lconv *locale_data = localeconv();
+ const char *decimal_point = locale_data->decimal_point;
+
+ if (decimal_point[0] != '.' || decimal_point[1] != 0) {
+ size_t decimal_point_len = strlen(decimal_point);
+
+ if (*buffer == '+' || *buffer == '-')
+ buffer++;
+ while (Py_ISDIGIT(*buffer))
+ buffer++;
+ if (strncmp(buffer, decimal_point, decimal_point_len) == 0) {
+ *buffer = '.';
+ buffer++;
+ if (decimal_point_len > 1) {
+ /* buffer needs to get smaller */
+ size_t rest_len = strlen(buffer +
+ (decimal_point_len - 1));
+ memmove(buffer,
+ buffer + (decimal_point_len - 1),
+ rest_len);
+ buffer[rest_len] = 0;
+ }
+ }
+ }
+}
+
+
+/* From the C99 standard, section 7.19.6:
+The exponent always contains at least two digits, and only as many more digits
+as necessary to represent the exponent.
+*/
+#define MIN_EXPONENT_DIGITS 2
+
+/* Ensure that any exponent, if present, is at least MIN_EXPONENT_DIGITS
+ in length. */
+Py_LOCAL_INLINE(void)
+ensure_minimum_exponent_length(char* buffer, size_t buf_size)
+{
+ char *p = strpbrk(buffer, "eE");
+ if (p && (*(p + 1) == '-' || *(p + 1) == '+')) {
+ char *start = p + 2;
+ int exponent_digit_cnt = 0;
+ int leading_zero_cnt = 0;
+ int in_leading_zeros = 1;
+ int significant_digit_cnt;
+
+ /* Skip over the exponent and the sign. */
+ p += 2;
+
+ /* Find the end of the exponent, keeping track of leading
+ zeros. */
+ while (*p && Py_ISDIGIT(*p)) {
+ if (in_leading_zeros && *p == '0')
+ ++leading_zero_cnt;
+ if (*p != '0')
+ in_leading_zeros = 0;
+ ++p;
+ ++exponent_digit_cnt;
+ }
+
+ significant_digit_cnt = exponent_digit_cnt - leading_zero_cnt;
+ if (exponent_digit_cnt == MIN_EXPONENT_DIGITS) {
+ /* If there are 2 exactly digits, we're done,
+ regardless of what they contain */
+ }
+ else if (exponent_digit_cnt > MIN_EXPONENT_DIGITS) {
+ int extra_zeros_cnt;
+
+ /* There are more than 2 digits in the exponent. See
+ if we can delete some of the leading zeros */
+ if (significant_digit_cnt < MIN_EXPONENT_DIGITS)
+ significant_digit_cnt = MIN_EXPONENT_DIGITS;
+ extra_zeros_cnt = exponent_digit_cnt -
+ significant_digit_cnt;
+
+ /* Delete extra_zeros_cnt worth of characters from the
+ front of the exponent */
+ assert(extra_zeros_cnt >= 0);
+
+ /* Add one to significant_digit_cnt to copy the
+ trailing 0 byte, thus setting the length */
+ memmove(start,
+ start + extra_zeros_cnt,
+ significant_digit_cnt + 1);
+ }
+ else {
+ /* If there are fewer than 2 digits, add zeros
+ until there are 2, if there's enough room */
+ int zeros = MIN_EXPONENT_DIGITS - exponent_digit_cnt;
+ if (start + zeros + exponent_digit_cnt + 1
+ < buffer + buf_size) {
+ memmove(start + zeros, start,
+ exponent_digit_cnt + 1);
+ memset(start, '0', zeros);
+ }
+ }
+ }
+}
+
+/* Remove trailing zeros after the decimal point from a numeric string; also
+ remove the decimal point if all digits following it are zero. The numeric
+ string must end in '\0', and should not have any leading or trailing
+ whitespace. Assumes that the decimal point is '.'. */
+Py_LOCAL_INLINE(void)
+remove_trailing_zeros(char *buffer)
+{
+ char *old_fraction_end, *new_fraction_end, *end, *p;
+
+ p = buffer;
+ if (*p == '-' || *p == '+')
+ /* Skip leading sign, if present */
+ ++p;
+ while (Py_ISDIGIT(*p))
+ ++p;
+
+ /* if there's no decimal point there's nothing to do */
+ if (*p++ != '.')
+ return;
+
+ /* scan any digits after the point */
+ while (Py_ISDIGIT(*p))
+ ++p;
+ old_fraction_end = p;
+
+ /* scan up to ending '\0' */
+ while (*p != '\0')
+ p++;
+ /* +1 to make sure that we move the null byte as well */
+ end = p+1;
+
+ /* scan back from fraction_end, looking for removable zeros */
+ p = old_fraction_end;
+ while (*(p-1) == '0')
+ --p;
+ /* and remove point if we've got that far */
+ if (*(p-1) == '.')
+ --p;
+ new_fraction_end = p;
+
+ memmove(new_fraction_end, old_fraction_end, end-old_fraction_end);
+}
+
+/* Ensure that buffer has a decimal point in it. The decimal point will not
+ be in the current locale, it will always be '.'. Don't add a decimal point
+ if an exponent is present. Also, convert to exponential notation where
+ adding a '.0' would produce too many significant digits (see issue 5864).
+
+ Returns a pointer to the fixed buffer, or NULL on failure.
+*/
+Py_LOCAL_INLINE(char *)
+ensure_decimal_point(char* buffer, size_t buf_size, int precision)
+{
+ int digit_count, insert_count = 0, convert_to_exp = 0;
+ const char *chars_to_insert;
+ char *digits_start;
+
+ /* search for the first non-digit character */
+ char *p = buffer;
+ if (*p == '-' || *p == '+')
+ /* Skip leading sign, if present. I think this could only
+ ever be '-', but it can't hurt to check for both. */
+ ++p;
+ digits_start = p;
+ while (*p && Py_ISDIGIT(*p))
+ ++p;
+ digit_count = Py_SAFE_DOWNCAST(p - digits_start, Py_ssize_t, int);
+
+ if (*p == '.') {
+ if (Py_ISDIGIT(*(p+1))) {
+ /* Nothing to do, we already have a decimal
+ point and a digit after it */
+ }
+ else {
+ /* We have a decimal point, but no following
+ digit. Insert a zero after the decimal. */
+ /* can't ever get here via PyOS_double_to_string */
+ assert(precision == -1);
+ ++p;
+ chars_to_insert = "0";
+ insert_count = 1;
+ }
+ }
+ else if (!(*p == 'e' || *p == 'E')) {
+ /* Don't add ".0" if we have an exponent. */
+ if (digit_count == precision) {
+ /* issue 5864: don't add a trailing .0 in the case
+ where the '%g'-formatted result already has as many
+ significant digits as were requested. Switch to
+ exponential notation instead. */
+ convert_to_exp = 1;
+ /* no exponent, no point, and we shouldn't land here
+ for infs and nans, so we must be at the end of the
+ string. */
+ assert(*p == '\0');
+ }
+ else {
+ assert(precision == -1 || digit_count < precision);
+ chars_to_insert = ".0";
+ insert_count = 2;
+ }
+ }
+ if (insert_count) {
+ size_t buf_len = strlen(buffer);
+ if (buf_len + insert_count + 1 >= buf_size) {
+ /* If there is not enough room in the buffer
+ for the additional text, just skip it. It's
+ not worth generating an error over. */
+ }
+ else {
+ memmove(p + insert_count, p,
+ buffer + strlen(buffer) - p + 1);
+ memcpy(p, chars_to_insert, insert_count);
+ }
+ }
+ if (convert_to_exp) {
+ int written;
+ size_t buf_avail;
+ p = digits_start;
+ /* insert decimal point */
+ assert(digit_count >= 1);
+ memmove(p+2, p+1, digit_count); /* safe, but overwrites nul */
+ p[1] = '.';
+ p += digit_count+1;
+ assert(p <= buf_size+buffer);
+ buf_avail = buf_size+buffer-p;
+ if (buf_avail == 0)
+ return NULL;
+ /* Add exponent. It's okay to use lower case 'e': we only
+ arrive here as a result of using the empty format code or
+ repr/str builtins and those never want an upper case 'E' */
+ written = PyOS_snprintf(p, buf_avail, "e%+.02d", digit_count-1);
+ if (!(0 <= written &&
+ written < Py_SAFE_DOWNCAST(buf_avail, size_t, int)))
+ /* output truncated, or something else bad happened */
+ return NULL;
+ remove_trailing_zeros(buffer);
+ }
+ return buffer;
+}
+
+/* see FORMATBUFLEN in unicodeobject.c */
+#define FLOAT_FORMATBUFLEN 120
+
+/**
+ * _PyOS_ascii_formatd:
+ * @buffer: A buffer to place the resulting string in
+ * @buf_size: The length of the buffer.
+ * @format: The printf()-style format to use for the
+ * code to use for converting.
+ * @d: The #gdouble to convert
+ * @precision: The precision to use when formatting.
+ *
+ * Converts a #gdouble to a string, using the '.' as
+ * decimal point. To format the number you pass in
+ * a printf()-style format string. Allowed conversion
+ * specifiers are 'e', 'E', 'f', 'F', 'g', 'G', and 'Z'.
+ *
+ * 'Z' is the same as 'g', except it always has a decimal and
+ * at least one digit after the decimal.
+ *
+ * Return value: The pointer to the buffer with the converted string.
+ * On failure returns NULL but does not set any Python exception.
+ **/
+static char *
+_PyOS_ascii_formatd(char *buffer,
+ size_t buf_size,
+ const char *format,
+ double d,
+ int precision)
+{
+ char format_char;
+ size_t format_len = strlen(format);
+
+ /* Issue 2264: code 'Z' requires copying the format. 'Z' is 'g', but
+ also with at least one character past the decimal. */
+ char tmp_format[FLOAT_FORMATBUFLEN];
+
+ /* The last character in the format string must be the format char */
+ format_char = format[format_len - 1];
+
+ if (format[0] != '%')
+ return NULL;
+
+ /* I'm not sure why this test is here. It's ensuring that the format
+ string after the first character doesn't have a single quote, a
+ lowercase l, or a percent. This is the reverse of the commented-out
+ test about 10 lines ago. */
+ if (strpbrk(format + 1, "'l%"))
+ return NULL;
+
+ /* Also curious about this function is that it accepts format strings
+ like "%xg", which are invalid for floats. In general, the
+ interface to this function is not very good, but changing it is
+ difficult because it's a public API. */
+
+ if (!(format_char == 'e' || format_char == 'E' ||
+ format_char == 'f' || format_char == 'F' ||
+ format_char == 'g' || format_char == 'G' ||
+ format_char == 'Z'))
+ return NULL;
+
+ /* Map 'Z' format_char to 'g', by copying the format string and
+ replacing the final char with a 'g' */
+ if (format_char == 'Z') {
+ if (format_len + 1 >= sizeof(tmp_format)) {
+ /* The format won't fit in our copy. Error out. In
+ practice, this will never happen and will be
+ detected by returning NULL */
+ return NULL;
+ }
+ strcpy(tmp_format, format);
+ tmp_format[format_len - 1] = 'g';
+ format = tmp_format;
+ }
+
+
+ /* Have PyOS_snprintf do the hard work */
+ PyOS_snprintf(buffer, buf_size, format, d);
+
+ /* Do various fixups on the return string */
+
+ /* Get the current locale, and find the decimal point string.
+ Convert that string back to a dot. */
+ change_decimal_from_locale_to_dot(buffer);
+
+ /* If an exponent exists, ensure that the exponent is at least
+ MIN_EXPONENT_DIGITS digits, providing the buffer is large enough
+ for the extra zeros. Also, if there are more than
+ MIN_EXPONENT_DIGITS, remove as many zeros as possible until we get
+ back to MIN_EXPONENT_DIGITS */
+ ensure_minimum_exponent_length(buffer, buf_size);
+
+ /* If format_char is 'Z', make sure we have at least one character
+ after the decimal point (and make sure we have a decimal point);
+ also switch to exponential notation in some edge cases where the
+ extra character would produce more significant digits that we
+ really want. */
+ if (format_char == 'Z')
+ buffer = ensure_decimal_point(buffer, buf_size, precision);
+
+ return buffer;
+}
+
+/* The fallback code to use if _Py_dg_dtoa is not available. */
+
+char * PyOS_double_to_string(double val,
+ char format_code,
+ int precision,
+ int flags,
+ int *type)
+{
+ char format[32];
+ Py_ssize_t bufsize;
+ char *buf;
+ int t, exp;
+ int upper = 0;
+
+ /* Validate format_code, and map upper and lower case */
+ switch (format_code) {
+ case 'e': /* exponent */
+ case 'f': /* fixed */
+ case 'g': /* general */
+ break;
+ case 'E':
+ upper = 1;
+ format_code = 'e';
+ break;
+ case 'F':
+ upper = 1;
+ format_code = 'f';
+ break;
+ case 'G':
+ upper = 1;
+ format_code = 'g';
+ break;
+ case 'r': /* repr format */
+ /* Supplied precision is unused, must be 0. */
+ if (precision != 0) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ /* The repr() precision (17 significant decimal digits) is the
+ minimal number that is guaranteed to have enough precision
+ so that if the number is read back in the exact same binary
+ value is recreated. This is true for IEEE floating point
+ by design, and also happens to work for all other modern
+ hardware. */
+ precision = 17;
+ format_code = 'g';
+ break;
+ default:
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+
+ /* Here's a quick-and-dirty calculation to figure out how big a buffer
+ we need. In general, for a finite float we need:
+
+ 1 byte for each digit of the decimal significand, and
+
+ 1 for a possible sign
+ 1 for a possible decimal point
+ 2 for a possible [eE][+-]
+ 1 for each digit of the exponent; if we allow 19 digits
+ total then we're safe up to exponents of 2**63.
+ 1 for the trailing nul byte
+
+ This gives a total of 24 + the number of digits in the significand,
+ and the number of digits in the significand is:
+
+ for 'g' format: at most precision, except possibly
+ when precision == 0, when it's 1.
+ for 'e' format: precision+1
+ for 'f' format: precision digits after the point, at least 1
+ before. To figure out how many digits appear before the point
+ we have to examine the size of the number. If fabs(val) < 1.0
+ then there will be only one digit before the point. If
+ fabs(val) >= 1.0, then there are at most
+
+ 1+floor(log10(ceiling(fabs(val))))
+
+ digits before the point (where the 'ceiling' allows for the
+ possibility that the rounding rounds the integer part of val
+ up). A safe upper bound for the above quantity is
+ 1+floor(exp/3), where exp is the unique integer such that 0.5
+ <= fabs(val)/2**exp < 1.0. This exp can be obtained from
+ frexp.
+
+ So we allow room for precision+1 digits for all formats, plus an
+ extra floor(exp/3) digits for 'f' format.
+
+ */
+
+ if (Py_IS_NAN(val) || Py_IS_INFINITY(val))
+ /* 3 for 'inf'/'nan', 1 for sign, 1 for '\0' */
+ bufsize = 5;
+ else {
+ bufsize = 25 + precision;
+ if (format_code == 'f' && fabs(val) >= 1.0) {
+ frexp(val, &exp);
+ bufsize += exp/3;
+ }
+ }
+
+ buf = PyMem_Malloc(bufsize);
+ if (buf == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ /* Handle nan and inf. */
+ if (Py_IS_NAN(val)) {
+ strcpy(buf, "nan");
+ t = Py_DTST_NAN;
+ } else if (Py_IS_INFINITY(val)) {
+ if (copysign(1., val) == 1.)
+ strcpy(buf, "inf");
+ else
+ strcpy(buf, "-inf");
+ t = Py_DTST_INFINITE;
+ } else {
+ t = Py_DTST_FINITE;
+ if (flags & Py_DTSF_ADD_DOT_0)
+ format_code = 'Z';
+
+ PyOS_snprintf(format, sizeof(format), "%%%s.%i%c",
+ (flags & Py_DTSF_ALT ? "#" : ""), precision,
+ format_code);
+ _PyOS_ascii_formatd(buf, bufsize, format, val, precision);
+ }
+
+ /* Add sign when requested. It's convenient (esp. when formatting
+ complex numbers) to include a sign even for inf and nan. */
+ if (flags & Py_DTSF_SIGN && buf[0] != '-') {
+ size_t len = strlen(buf);
+ /* the bufsize calculations above should ensure that we've got
+ space to add a sign */
+ assert((size_t)bufsize >= len+2);
+ memmove(buf+1, buf, len+1);
+ buf[0] = '+';
+ }
+ if (upper) {
+ /* Convert to upper case. */
+ char *p1;
+ for (p1 = buf; *p1; p1++)
+ *p1 = Py_TOUPPER(*p1);
+ }
+
+ if (type)
+ *type = t;
+ return buf;
+}
+
+#else
+
+/* _Py_dg_dtoa is available. */
+
+/* I'm using a lookup table here so that I don't have to invent a non-locale
+ specific way to convert to uppercase */
+#define OFS_INF 0
+#define OFS_NAN 1
+#define OFS_E 2
+
+/* The lengths of these are known to the code below, so don't change them */
+static const char * const lc_float_strings[] = {
+ "inf",
+ "nan",
+ "e",
+};
+static const char * const uc_float_strings[] = {
+ "INF",
+ "NAN",
+ "E",
+};
+
+
+/* Convert a double d to a string, and return a PyMem_Malloc'd block of
+ memory contain the resulting string.
+
+ Arguments:
+ d is the double to be converted
+ format_code is one of 'e', 'f', 'g', 'r'. 'e', 'f' and 'g'
+ correspond to '%e', '%f' and '%g'; 'r' corresponds to repr.
+ mode is one of '0', '2' or '3', and is completely determined by
+ format_code: 'e' and 'g' use mode 2; 'f' mode 3, 'r' mode 0.
+ precision is the desired precision
+ always_add_sign is nonzero if a '+' sign should be included for positive
+ numbers
+ add_dot_0_if_integer is nonzero if integers in non-exponential form
+ should have ".0" added. Only applies to format codes 'r' and 'g'.
+ use_alt_formatting is nonzero if alternative formatting should be
+ used. Only applies to format codes 'e', 'f' and 'g'. For code 'g',
+ at most one of use_alt_formatting and add_dot_0_if_integer should
+ be nonzero.
+ type, if non-NULL, will be set to one of these constants to identify
+ the type of the 'd' argument:
+ Py_DTST_FINITE
+ Py_DTST_INFINITE
+ Py_DTST_NAN
+
+ Returns a PyMem_Malloc'd block of memory containing the resulting string,
+ or NULL on error. If NULL is returned, the Python error has been set.
+ */
+
+static char *
+format_float_short(double d, char format_code,
+ int mode, int precision,
+ int always_add_sign, int add_dot_0_if_integer,
+ int use_alt_formatting, const char * const *float_strings,
+ int *type)
+{
+ char *buf = NULL;
+ char *p = NULL;
+ Py_ssize_t bufsize = 0;
+ char *digits, *digits_end;
+ int decpt_as_int, sign, exp_len, exp = 0, use_exp = 0;
+ Py_ssize_t decpt, digits_len, vdigits_start, vdigits_end;
+ _Py_SET_53BIT_PRECISION_HEADER;
+
+ /* _Py_dg_dtoa returns a digit string (no decimal point or exponent).
+ Must be matched by a call to _Py_dg_freedtoa. */
+ _Py_SET_53BIT_PRECISION_START;
+ digits = _Py_dg_dtoa(d, mode, precision, &decpt_as_int, &sign,
+ &digits_end);
+ _Py_SET_53BIT_PRECISION_END;
+
+ decpt = (Py_ssize_t)decpt_as_int;
+ if (digits == NULL) {
+ /* The only failure mode is no memory. */
+ PyErr_NoMemory();
+ goto exit;
+ }
+ assert(digits_end != NULL && digits_end >= digits);
+ digits_len = digits_end - digits;
+
+ if (digits_len && !Py_ISDIGIT(digits[0])) {
+ /* Infinities and nans here; adapt Gay's output,
+ so convert Infinity to inf and NaN to nan, and
+ ignore sign of nan. Then return. */
+
+ /* ignore the actual sign of a nan */
+ if (digits[0] == 'n' || digits[0] == 'N')
+ sign = 0;
+
+ /* We only need 5 bytes to hold the result "+inf\0" . */
+ bufsize = 5; /* Used later in an assert. */
+ buf = (char *)PyMem_Malloc(bufsize);
+ if (buf == NULL) {
+ PyErr_NoMemory();
+ goto exit;
+ }
+ p = buf;
+
+ if (sign == 1) {
+ *p++ = '-';
+ }
+ else if (always_add_sign) {
+ *p++ = '+';
+ }
+ if (digits[0] == 'i' || digits[0] == 'I') {
+ strncpy(p, float_strings[OFS_INF], 3);
+ p += 3;
+
+ if (type)
+ *type = Py_DTST_INFINITE;
+ }
+ else if (digits[0] == 'n' || digits[0] == 'N') {
+ strncpy(p, float_strings[OFS_NAN], 3);
+ p += 3;
+
+ if (type)
+ *type = Py_DTST_NAN;
+ }
+ else {
+ /* shouldn't get here: Gay's code should always return
+ something starting with a digit, an 'I', or 'N' */
+ Py_UNREACHABLE();
+ }
+ goto exit;
+ }
+
+ /* The result must be finite (not inf or nan). */
+ if (type)
+ *type = Py_DTST_FINITE;
+
+
+ /* We got digits back, format them. We may need to pad 'digits'
+ either on the left or right (or both) with extra zeros, so in
+ general the resulting string has the form
+
+ [<sign>]<zeros><digits><zeros>[<exponent>]
+
+ where either of the <zeros> pieces could be empty, and there's a
+ decimal point that could appear either in <digits> or in the
+ leading or trailing <zeros>.
+
+ Imagine an infinite 'virtual' string vdigits, consisting of the
+ string 'digits' (starting at index 0) padded on both the left and
+ right with infinite strings of zeros. We want to output a slice
+
+ vdigits[vdigits_start : vdigits_end]
+
+ of this virtual string. Thus if vdigits_start < 0 then we'll end
+ up producing some leading zeros; if vdigits_end > digits_len there
+ will be trailing zeros in the output. The next section of code
+ determines whether to use an exponent or not, figures out the
+ position 'decpt' of the decimal point, and computes 'vdigits_start'
+ and 'vdigits_end'. */
+ vdigits_end = digits_len;
+ switch (format_code) {
+ case 'e':
+ use_exp = 1;
+ vdigits_end = precision;
+ break;
+ case 'f':
+ vdigits_end = decpt + precision;
+ break;
+ case 'g':
+ if (decpt <= -4 || decpt >
+ (add_dot_0_if_integer ? precision-1 : precision))
+ use_exp = 1;
+ if (use_alt_formatting)
+ vdigits_end = precision;
+ break;
+ case 'r':
+ /* convert to exponential format at 1e16. We used to convert
+ at 1e17, but that gives odd-looking results for some values
+ when a 16-digit 'shortest' repr is padded with bogus zeros.
+ For example, repr(2e16+8) would give 20000000000000010.0;
+ the true value is 20000000000000008.0. */
+ if (decpt <= -4 || decpt > 16)
+ use_exp = 1;
+ break;
+ default:
+ PyErr_BadInternalCall();
+ goto exit;
+ }
+
+ /* if using an exponent, reset decimal point position to 1 and adjust
+ exponent accordingly.*/
+ if (use_exp) {
+ exp = (int)decpt - 1;
+ decpt = 1;
+ }
+ /* ensure vdigits_start < decpt <= vdigits_end, or vdigits_start <
+ decpt < vdigits_end if add_dot_0_if_integer and no exponent */
+ vdigits_start = decpt <= 0 ? decpt-1 : 0;
+ if (!use_exp && add_dot_0_if_integer)
+ vdigits_end = vdigits_end > decpt ? vdigits_end : decpt + 1;
+ else
+ vdigits_end = vdigits_end > decpt ? vdigits_end : decpt;
+
+ /* double check inequalities */
+ assert(vdigits_start <= 0 &&
+ 0 <= digits_len &&
+ digits_len <= vdigits_end);
+ /* decimal point should be in (vdigits_start, vdigits_end] */
+ assert(vdigits_start < decpt && decpt <= vdigits_end);
+
+ /* Compute an upper bound how much memory we need. This might be a few
+ chars too long, but no big deal. */
+ bufsize =
+ /* sign, decimal point and trailing 0 byte */
+ 3 +
+
+ /* total digit count (including zero padding on both sides) */
+ (vdigits_end - vdigits_start) +
+
+ /* exponent "e+100", max 3 numerical digits */
+ (use_exp ? 5 : 0);
+
+ /* Now allocate the memory and initialize p to point to the start of
+ it. */
+ buf = (char *)PyMem_Malloc(bufsize);
+ if (buf == NULL) {
+ PyErr_NoMemory();
+ goto exit;
+ }
+ p = buf;
+
+ /* Add a negative sign if negative, and a plus sign if non-negative
+ and always_add_sign is true. */
+ if (sign == 1)
+ *p++ = '-';
+ else if (always_add_sign)
+ *p++ = '+';
+
+ /* note that exactly one of the three 'if' conditions is true,
+ so we include exactly one decimal point */
+ /* Zero padding on left of digit string */
+ if (decpt <= 0) {
+ memset(p, '0', decpt-vdigits_start);
+ p += decpt - vdigits_start;
+ *p++ = '.';
+ memset(p, '0', 0-decpt);
+ p += 0-decpt;
+ }
+ else {
+ memset(p, '0', 0-vdigits_start);
+ p += 0 - vdigits_start;
+ }
+
+ /* Digits, with included decimal point */
+ if (0 < decpt && decpt <= digits_len) {
+ strncpy(p, digits, decpt-0);
+ p += decpt-0;
+ *p++ = '.';
+ strncpy(p, digits+decpt, digits_len-decpt);
+ p += digits_len-decpt;
+ }
+ else {
+ strncpy(p, digits, digits_len);
+ p += digits_len;
+ }
+
+ /* And zeros on the right */
+ if (digits_len < decpt) {
+ memset(p, '0', decpt-digits_len);
+ p += decpt-digits_len;
+ *p++ = '.';
+ memset(p, '0', vdigits_end-decpt);
+ p += vdigits_end-decpt;
+ }
+ else {
+ memset(p, '0', vdigits_end-digits_len);
+ p += vdigits_end-digits_len;
+ }
+
+ /* Delete a trailing decimal pt unless using alternative formatting. */
+ if (p[-1] == '.' && !use_alt_formatting)
+ p--;
+
+ /* Now that we've done zero padding, add an exponent if needed. */
+ if (use_exp) {
+ *p++ = float_strings[OFS_E][0];
+ exp_len = sprintf(p, "%+.02d", exp);
+ p += exp_len;
+ }
+ exit:
+ if (buf) {
+ *p = '\0';
+ /* It's too late if this fails, as we've already stepped on
+ memory that isn't ours. But it's an okay debugging test. */
+ assert(p-buf < bufsize);
+ }
+ if (digits)
+ _Py_dg_freedtoa(digits);
+
+ return buf;
+}
+
+
+char * PyOS_double_to_string(double val,
+ char format_code,
+ int precision,
+ int flags,
+ int *type)
+{
+ const char * const *float_strings = lc_float_strings;
+ int mode;
+
+ /* Validate format_code, and map upper and lower case. Compute the
+ mode and make any adjustments as needed. */
+ switch (format_code) {
+ /* exponent */
+ case 'E':
+ float_strings = uc_float_strings;
+ format_code = 'e';
+ /* Fall through. */
+ case 'e':
+ mode = 2;
+ precision++;
+ break;
+
+ /* fixed */
+ case 'F':
+ float_strings = uc_float_strings;
+ format_code = 'f';
+ /* Fall through. */
+ case 'f':
+ mode = 3;
+ break;
+
+ /* general */
+ case 'G':
+ float_strings = uc_float_strings;
+ format_code = 'g';
+ /* Fall through. */
+ case 'g':
+ mode = 2;
+ /* precision 0 makes no sense for 'g' format; interpret as 1 */
+ if (precision == 0)
+ precision = 1;
+ break;
+
+ /* repr format */
+ case 'r':
+ mode = 0;
+ /* Supplied precision is unused, must be 0. */
+ if (precision != 0) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ break;
+
+ default:
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+
+ return format_float_short(val, format_code, mode, precision,
+ flags & Py_DTSF_SIGN,
+ flags & Py_DTSF_ADD_DOT_0,
+ flags & Py_DTSF_ALT,
+ float_strings, type);
+}
+#endif /* ifdef PY_NO_SHORT_FLOAT_REPR */
diff --git a/contrib/tools/python3/src/Python/pythonrun.c b/contrib/tools/python3/src/Python/pythonrun.c
new file mode 100644
index 00000000000..364101e99de
--- /dev/null
+++ b/contrib/tools/python3/src/Python/pythonrun.c
@@ -0,0 +1,1880 @@
+
+/* Top level execution of Python code (including in __main__) */
+
+/* To help control the interfaces between the startup, execution and
+ * shutdown code, the phases are split across separate modules (bootstrap,
+ * pythonrun, shutdown)
+ */
+
+/* TODO: Cull includes following phase split */
+
+#include "Python.h"
+
+#include "Python-ast.h"
+#undef Yield /* undefine macro conflicting with <winbase.h> */
+
+#include "pycore_interp.h" // PyInterpreterState.importlib
+#include "pycore_object.h" // _PyDebug_PrintTotalRefs(),
+ // _PyType_GetQualName()
+#include "pycore_pyerrors.h" // _PyErr_Fetch
+#include "pycore_pylifecycle.h" // _Py_UnhandledKeyboardInterrupt
+#include "pycore_pystate.h" // _PyInterpreterState_GET()
+#include "pycore_sysmodule.h" // _PySys_Audit()
+
+#include "node.h" // node
+#include "token.h" // INDENT
+#include "parsetok.h" // perrdetail
+#include "errcode.h" // E_EOF
+#include "code.h" // PyCodeObject
+#include "symtable.h" // PySymtable_BuildObject()
+#include "ast.h" // PyAST_FromNodeObject()
+#include "marshal.h" // PyMarshal_ReadLongFromFile()
+
+#include "pegen_interface.h" // PyPegen_ASTFrom*
+
+#ifdef MS_WINDOWS
+# include "malloc.h" // alloca()
+#endif
+
+#ifdef MS_WINDOWS
+# undef BYTE
+# include "windows.h"
+#endif
+
+
+_Py_IDENTIFIER(builtins);
+_Py_IDENTIFIER(excepthook);
+_Py_IDENTIFIER(flush);
+_Py_IDENTIFIER(last_traceback);
+_Py_IDENTIFIER(last_type);
+_Py_IDENTIFIER(last_value);
+_Py_IDENTIFIER(ps1);
+_Py_IDENTIFIER(ps2);
+_Py_IDENTIFIER(stdin);
+_Py_IDENTIFIER(stdout);
+_Py_IDENTIFIER(stderr);
+_Py_static_string(PyId_string, "<string>");
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern Py_EXPORTED_SYMBOL grammar _PyParser_Grammar; /* From graminit.c */
+
+/* Forward */
+static void flush_io(void);
+static PyObject *run_mod(mod_ty, PyObject *, PyObject *, PyObject *,
+ PyCompilerFlags *, PyArena *);
+static PyObject *run_pyc_file(FILE *, PyObject *, PyObject *,
+ PyCompilerFlags *);
+static void err_input(perrdetail *);
+static void err_free(perrdetail *);
+static int PyRun_InteractiveOneObjectEx(FILE *, PyObject *, PyCompilerFlags *);
+static PyObject* pyrun_file(FILE *fp, PyObject *filename, int start,
+ PyObject *globals, PyObject *locals, int closeit,
+ PyCompilerFlags *flags);
+
+
+/* Parse input from a file and execute it */
+int
+PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit,
+ PyCompilerFlags *flags)
+{
+ if (filename == NULL)
+ filename = "???";
+ if (Py_FdIsInteractive(fp, filename)) {
+ int err = PyRun_InteractiveLoopFlags(fp, filename, flags);
+ if (closeit)
+ fclose(fp);
+ return err;
+ }
+ else
+ return PyRun_SimpleFileExFlags(fp, filename, closeit, flags);
+}
+
+int
+PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *flags)
+{
+ PyObject *filename, *v;
+ int ret, err;
+ PyCompilerFlags local_flags = _PyCompilerFlags_INIT;
+ int nomem_count = 0;
+#ifdef Py_REF_DEBUG
+ int show_ref_count = _Py_GetConfig()->show_ref_count;
+#endif
+
+ filename = PyUnicode_DecodeFSDefault(filename_str);
+ if (filename == NULL) {
+ PyErr_Print();
+ return -1;
+ }
+
+ if (flags == NULL) {
+ flags = &local_flags;
+ }
+ v = _PySys_GetObjectId(&PyId_ps1);
+ if (v == NULL) {
+ _PySys_SetObjectId(&PyId_ps1, v = PyUnicode_FromString(">>> "));
+ Py_XDECREF(v);
+ }
+ v = _PySys_GetObjectId(&PyId_ps2);
+ if (v == NULL) {
+ _PySys_SetObjectId(&PyId_ps2, v = PyUnicode_FromString("... "));
+ Py_XDECREF(v);
+ }
+ err = 0;
+ do {
+ ret = PyRun_InteractiveOneObjectEx(fp, filename, flags);
+ if (ret == -1 && PyErr_Occurred()) {
+ /* Prevent an endless loop after multiple consecutive MemoryErrors
+ * while still allowing an interactive command to fail with a
+ * MemoryError. */
+ if (PyErr_ExceptionMatches(PyExc_MemoryError)) {
+ if (++nomem_count > 16) {
+ PyErr_Clear();
+ err = -1;
+ break;
+ }
+ } else {
+ nomem_count = 0;
+ }
+ PyErr_Print();
+ flush_io();
+ } else {
+ nomem_count = 0;
+ }
+#ifdef Py_REF_DEBUG
+ if (show_ref_count) {
+ _PyDebug_PrintTotalRefs();
+ }
+#endif
+ } while (ret != E_EOF);
+ Py_DECREF(filename);
+ return err;
+}
+
+/* compute parser flags based on compiler flags */
+static int PARSER_FLAGS(PyCompilerFlags *flags)
+{
+ int parser_flags = 0;
+ if (!flags)
+ return 0;
+ if (flags->cf_flags & PyCF_DONT_IMPLY_DEDENT)
+ parser_flags |= PyPARSE_DONT_IMPLY_DEDENT;
+ if (flags->cf_flags & PyCF_IGNORE_COOKIE)
+ parser_flags |= PyPARSE_IGNORE_COOKIE;
+ if (flags->cf_flags & CO_FUTURE_BARRY_AS_BDFL)
+ parser_flags |= PyPARSE_BARRY_AS_BDFL;
+ if (flags->cf_flags & PyCF_TYPE_COMMENTS)
+ parser_flags |= PyPARSE_TYPE_COMMENTS;
+ return parser_flags;
+}
+
+#if 0
+/* Keep an example of flags with future keyword support. */
+#define PARSER_FLAGS(flags) \
+ ((flags) ? ((((flags)->cf_flags & PyCF_DONT_IMPLY_DEDENT) ? \
+ PyPARSE_DONT_IMPLY_DEDENT : 0) \
+ | ((flags)->cf_flags & CO_FUTURE_WITH_STATEMENT ? \
+ PyPARSE_WITH_IS_KEYWORD : 0)) : 0)
+#endif
+
+/* A PyRun_InteractiveOneObject() auxiliary function that does not print the
+ * error on failure. */
+static int
+PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename,
+ PyCompilerFlags *flags)
+{
+ PyObject *m, *d, *v, *w, *oenc = NULL, *mod_name;
+ mod_ty mod;
+ PyArena *arena;
+ const char *ps1 = "", *ps2 = "", *enc = NULL;
+ int errcode = 0;
+ int use_peg = _PyInterpreterState_GET()->config._use_peg_parser;
+ _Py_IDENTIFIER(encoding);
+ _Py_IDENTIFIER(__main__);
+
+ mod_name = _PyUnicode_FromId(&PyId___main__); /* borrowed */
+ if (mod_name == NULL) {
+ return -1;
+ }
+
+ if (fp == stdin) {
+ /* Fetch encoding from sys.stdin if possible. */
+ v = _PySys_GetObjectId(&PyId_stdin);
+ if (v && v != Py_None) {
+ oenc = _PyObject_GetAttrId(v, &PyId_encoding);
+ if (oenc)
+ enc = PyUnicode_AsUTF8(oenc);
+ if (!enc)
+ PyErr_Clear();
+ }
+ }
+ v = _PySys_GetObjectId(&PyId_ps1);
+ if (v != NULL) {
+ v = PyObject_Str(v);
+ if (v == NULL)
+ PyErr_Clear();
+ else if (PyUnicode_Check(v)) {
+ ps1 = PyUnicode_AsUTF8(v);
+ if (ps1 == NULL) {
+ PyErr_Clear();
+ ps1 = "";
+ }
+ }
+ }
+ w = _PySys_GetObjectId(&PyId_ps2);
+ if (w != NULL) {
+ w = PyObject_Str(w);
+ if (w == NULL)
+ PyErr_Clear();
+ else if (PyUnicode_Check(w)) {
+ ps2 = PyUnicode_AsUTF8(w);
+ if (ps2 == NULL) {
+ PyErr_Clear();
+ ps2 = "";
+ }
+ }
+ }
+ arena = PyArena_New();
+ if (arena == NULL) {
+ Py_XDECREF(v);
+ Py_XDECREF(w);
+ Py_XDECREF(oenc);
+ return -1;
+ }
+
+ if (use_peg) {
+ mod = PyPegen_ASTFromFileObject(fp, filename, Py_single_input,
+ enc, ps1, ps2, flags, &errcode, arena);
+ }
+ else {
+ mod = PyParser_ASTFromFileObject(fp, filename, enc,
+ Py_single_input, ps1, ps2,
+ flags, &errcode, arena);
+ }
+
+ Py_XDECREF(v);
+ Py_XDECREF(w);
+ Py_XDECREF(oenc);
+ if (mod == NULL) {
+ PyArena_Free(arena);
+ if (errcode == E_EOF) {
+ PyErr_Clear();
+ return E_EOF;
+ }
+ return -1;
+ }
+ m = PyImport_AddModuleObject(mod_name);
+ if (m == NULL) {
+ PyArena_Free(arena);
+ return -1;
+ }
+ d = PyModule_GetDict(m);
+ v = run_mod(mod, filename, d, d, flags, arena);
+ PyArena_Free(arena);
+ if (v == NULL) {
+ return -1;
+ }
+ Py_DECREF(v);
+ flush_io();
+ return 0;
+}
+
+int
+PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)
+{
+ int res;
+
+ res = PyRun_InteractiveOneObjectEx(fp, filename, flags);
+ if (res == -1) {
+ PyErr_Print();
+ flush_io();
+ }
+ return res;
+}
+
+int
+PyRun_InteractiveOneFlags(FILE *fp, const char *filename_str, PyCompilerFlags *flags)
+{
+ PyObject *filename;
+ int res;
+
+ filename = PyUnicode_DecodeFSDefault(filename_str);
+ if (filename == NULL) {
+ PyErr_Print();
+ return -1;
+ }
+ res = PyRun_InteractiveOneObject(fp, filename, flags);
+ Py_DECREF(filename);
+ return res;
+}
+
+
+/* Check whether a file maybe a pyc file: Look at the extension,
+ the file type, and, if we may close it, at the first few bytes. */
+
+static int
+maybe_pyc_file(FILE *fp, PyObject *filename, int closeit)
+{
+ PyObject *ext = PyUnicode_FromString(".pyc");
+ if (ext == NULL) {
+ return -1;
+ }
+ Py_ssize_t endswith = PyUnicode_Tailmatch(filename, ext, 0, PY_SSIZE_T_MAX, +1);
+ Py_DECREF(ext);
+ if (endswith) {
+ return 1;
+ }
+
+ /* Only look into the file if we are allowed to close it, since
+ it then should also be seekable. */
+ if (!closeit) {
+ return 0;
+ }
+
+ /* Read only two bytes of the magic. If the file was opened in
+ text mode, the bytes 3 and 4 of the magic (\r\n) might not
+ be read as they are on disk. */
+ unsigned int halfmagic = PyImport_GetMagicNumber() & 0xFFFF;
+ unsigned char buf[2];
+ /* Mess: In case of -x, the stream is NOT at its start now,
+ and ungetc() was used to push back the first newline,
+ which makes the current stream position formally undefined,
+ and a x-platform nightmare.
+ Unfortunately, we have no direct way to know whether -x
+ was specified. So we use a terrible hack: if the current
+ stream position is not 0, we assume -x was specified, and
+ give up. Bug 132850 on SourceForge spells out the
+ hopelessness of trying anything else (fseek and ftell
+ don't work predictably x-platform for text-mode files).
+ */
+ int ispyc = 0;
+ if (ftell(fp) == 0) {
+ if (fread(buf, 1, 2, fp) == 2 &&
+ ((unsigned int)buf[1]<<8 | buf[0]) == halfmagic)
+ ispyc = 1;
+ rewind(fp);
+ }
+ return ispyc;
+}
+
+
+static int
+set_main_loader(PyObject *d, PyObject *filename, const char *loader_name)
+{
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ PyObject *bootstrap = PyObject_GetAttrString(interp->importlib,
+ "_bootstrap_external");
+ if (bootstrap == NULL) {
+ return -1;
+ }
+
+ PyObject *loader_type = PyObject_GetAttrString(bootstrap, loader_name);
+ Py_DECREF(bootstrap);
+ if (loader_type == NULL) {
+ return -1;
+ }
+
+ PyObject *loader = PyObject_CallFunction(loader_type,
+ "sO", "__main__", filename);
+ Py_DECREF(loader_type);
+ if (loader == NULL) {
+ return -1;
+ }
+
+ if (PyDict_SetItemString(d, "__loader__", loader) < 0) {
+ Py_DECREF(loader);
+ return -1;
+ }
+ Py_DECREF(loader);
+ return 0;
+}
+
+
+static int
+pyrun_simple_file(FILE *fp, PyObject *filename, int closeit,
+ PyCompilerFlags *flags)
+{
+ PyObject *m, *d, *v;
+ int set_file_name = 0, ret = -1;
+
+ m = PyImport_AddModule("__main__");
+ if (m == NULL)
+ return -1;
+ Py_INCREF(m);
+ d = PyModule_GetDict(m);
+ if (PyDict_GetItemString(d, "__file__") == NULL) {
+ if (PyDict_SetItemString(d, "__file__", filename) < 0) {
+ goto done;
+ }
+ if (PyDict_SetItemString(d, "__cached__", Py_None) < 0) {
+ goto done;
+ }
+ set_file_name = 1;
+ }
+
+ int pyc = maybe_pyc_file(fp, filename, closeit);
+ if (pyc < 0) {
+ goto done;
+ }
+
+ if (pyc) {
+ FILE *pyc_fp;
+ /* Try to run a pyc file. First, re-open in binary */
+ if (closeit) {
+ fclose(fp);
+ }
+
+ pyc_fp = _Py_fopen_obj(filename, "rb");
+ if (pyc_fp == NULL) {
+ fprintf(stderr, "python: Can't reopen .pyc file\n");
+ goto done;
+ }
+
+ if (set_main_loader(d, filename, "SourcelessFileLoader") < 0) {
+ fprintf(stderr, "python: failed to set __main__.__loader__\n");
+ ret = -1;
+ fclose(pyc_fp);
+ goto done;
+ }
+ v = run_pyc_file(pyc_fp, d, d, flags);
+ } else {
+ /* When running from stdin, leave __main__.__loader__ alone */
+ if (PyUnicode_CompareWithASCIIString(filename, "<stdin>") != 0 &&
+ set_main_loader(d, filename, "SourceFileLoader") < 0) {
+ fprintf(stderr, "python: failed to set __main__.__loader__\n");
+ ret = -1;
+ goto done;
+ }
+ v = pyrun_file(fp, filename, Py_file_input, d, d,
+ closeit, flags);
+ }
+ flush_io();
+ if (v == NULL) {
+ Py_CLEAR(m);
+ PyErr_Print();
+ goto done;
+ }
+ Py_DECREF(v);
+ ret = 0;
+ done:
+ if (set_file_name) {
+ if (PyDict_DelItemString(d, "__file__")) {
+ PyErr_Clear();
+ }
+ if (PyDict_DelItemString(d, "__cached__")) {
+ PyErr_Clear();
+ }
+ }
+ Py_XDECREF(m);
+ return ret;
+}
+
+
+int
+PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,
+ PyCompilerFlags *flags)
+{
+ PyObject *filename_obj = PyUnicode_DecodeFSDefault(filename);
+ if (filename_obj == NULL) {
+ return -1;
+ }
+ int res = pyrun_simple_file(fp, filename_obj, closeit, flags);
+ Py_DECREF(filename_obj);
+ return res;
+}
+
+
+int
+PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags)
+{
+ PyObject *m, *d, *v;
+ m = PyImport_AddModule("__main__");
+ if (m == NULL)
+ return -1;
+ d = PyModule_GetDict(m);
+ v = PyRun_StringFlags(command, Py_file_input, d, d, flags);
+ if (v == NULL) {
+ PyErr_Print();
+ return -1;
+ }
+ Py_DECREF(v);
+ return 0;
+}
+
+static int
+parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename,
+ Py_ssize_t *lineno, Py_ssize_t *offset, PyObject **text)
+{
+ Py_ssize_t hold;
+ PyObject *v;
+ _Py_IDENTIFIER(msg);
+ _Py_IDENTIFIER(filename);
+ _Py_IDENTIFIER(lineno);
+ _Py_IDENTIFIER(offset);
+ _Py_IDENTIFIER(text);
+
+ *message = NULL;
+ *filename = NULL;
+
+ /* new style errors. `err' is an instance */
+ *message = _PyObject_GetAttrId(err, &PyId_msg);
+ if (!*message)
+ goto finally;
+
+ v = _PyObject_GetAttrId(err, &PyId_filename);
+ if (!v)
+ goto finally;
+ if (v == Py_None) {
+ Py_DECREF(v);
+ *filename = _PyUnicode_FromId(&PyId_string);
+ if (*filename == NULL)
+ goto finally;
+ Py_INCREF(*filename);
+ }
+ else {
+ *filename = v;
+ }
+
+ v = _PyObject_GetAttrId(err, &PyId_lineno);
+ if (!v)
+ goto finally;
+ hold = PyLong_AsSsize_t(v);
+ Py_DECREF(v);
+ if (hold < 0 && PyErr_Occurred())
+ goto finally;
+ *lineno = hold;
+
+ v = _PyObject_GetAttrId(err, &PyId_offset);
+ if (!v)
+ goto finally;
+ if (v == Py_None) {
+ *offset = -1;
+ Py_DECREF(v);
+ } else {
+ hold = PyLong_AsSsize_t(v);
+ Py_DECREF(v);
+ if (hold < 0 && PyErr_Occurred())
+ goto finally;
+ *offset = hold;
+ }
+
+ v = _PyObject_GetAttrId(err, &PyId_text);
+ if (!v)
+ goto finally;
+ if (v == Py_None) {
+ Py_DECREF(v);
+ *text = NULL;
+ }
+ else {
+ *text = v;
+ }
+ return 1;
+
+finally:
+ Py_XDECREF(*message);
+ Py_XDECREF(*filename);
+ return 0;
+}
+
+static void
+print_error_text(PyObject *f, Py_ssize_t offset, PyObject *text_obj)
+{
+ /* Convert text to a char pointer; return if error */
+ const char *text = PyUnicode_AsUTF8(text_obj);
+ if (text == NULL)
+ return;
+
+ /* Convert offset from 1-based to 0-based */
+ offset--;
+
+ /* Strip leading whitespace from text, adjusting offset as we go */
+ while (*text == ' ' || *text == '\t' || *text == '\f') {
+ text++;
+ offset--;
+ }
+
+ /* Calculate text length excluding trailing newline */
+ Py_ssize_t len = strlen(text);
+ if (len > 0 && text[len-1] == '\n') {
+ len--;
+ }
+
+ /* Clip offset to at most len */
+ if (offset > len) {
+ offset = len;
+ }
+
+ /* Skip past newlines embedded in text */
+ for (;;) {
+ const char *nl = strchr(text, '\n');
+ if (nl == NULL) {
+ break;
+ }
+ Py_ssize_t inl = nl - text;
+ if (inl >= offset) {
+ break;
+ }
+ inl += 1;
+ text += inl;
+ len -= inl;
+ offset -= (int)inl;
+ }
+
+ /* Print text */
+ PyFile_WriteString(" ", f);
+ PyFile_WriteString(text, f);
+
+ /* Make sure there's a newline at the end */
+ if (text[len] != '\n') {
+ PyFile_WriteString("\n", f);
+ }
+
+ /* Don't print caret if it points to the left of the text */
+ if (offset < 0)
+ return;
+
+ /* Write caret line */
+ PyFile_WriteString(" ", f);
+ while (--offset >= 0) {
+ PyFile_WriteString(" ", f);
+ }
+ PyFile_WriteString("^\n", f);
+}
+
+
+int
+_Py_HandleSystemExit(int *exitcode_p)
+{
+ int inspect = _Py_GetConfig()->inspect;
+ if (inspect) {
+ /* Don't exit if -i flag was given. This flag is set to 0
+ * when entering interactive mode for inspecting. */
+ return 0;
+ }
+
+ if (!PyErr_ExceptionMatches(PyExc_SystemExit)) {
+ return 0;
+ }
+
+ PyObject *exception, *value, *tb;
+ PyErr_Fetch(&exception, &value, &tb);
+
+ fflush(stdout);
+
+ int exitcode = 0;
+ if (value == NULL || value == Py_None) {
+ goto done;
+ }
+
+ if (PyExceptionInstance_Check(value)) {
+ /* The error code should be in the `code' attribute. */
+ _Py_IDENTIFIER(code);
+ PyObject *code = _PyObject_GetAttrId(value, &PyId_code);
+ if (code) {
+ Py_DECREF(value);
+ value = code;
+ if (value == Py_None)
+ goto done;
+ }
+ /* If we failed to dig out the 'code' attribute,
+ just let the else clause below print the error. */
+ }
+
+ if (PyLong_Check(value)) {
+ exitcode = (int)PyLong_AsLong(value);
+ }
+ else {
+ PyObject *sys_stderr = _PySys_GetObjectId(&PyId_stderr);
+ /* We clear the exception here to avoid triggering the assertion
+ * in PyObject_Str that ensures it won't silently lose exception
+ * details.
+ */
+ PyErr_Clear();
+ if (sys_stderr != NULL && sys_stderr != Py_None) {
+ PyFile_WriteObject(value, sys_stderr, Py_PRINT_RAW);
+ } else {
+ PyObject_Print(value, stderr, Py_PRINT_RAW);
+ fflush(stderr);
+ }
+ PySys_WriteStderr("\n");
+ exitcode = 1;
+ }
+
+ done:
+ /* Restore and clear the exception info, in order to properly decref
+ * the exception, value, and traceback. If we just exit instead,
+ * these leak, which confuses PYTHONDUMPREFS output, and may prevent
+ * some finalizers from running.
+ */
+ PyErr_Restore(exception, value, tb);
+ PyErr_Clear();
+ *exitcode_p = exitcode;
+ return 1;
+}
+
+
+static void
+handle_system_exit(void)
+{
+ int exitcode;
+ if (_Py_HandleSystemExit(&exitcode)) {
+ Py_Exit(exitcode);
+ }
+}
+
+
+static void
+_PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars)
+{
+ PyObject *exception, *v, *tb, *hook;
+
+ handle_system_exit();
+
+ _PyErr_Fetch(tstate, &exception, &v, &tb);
+ if (exception == NULL) {
+ goto done;
+ }
+
+ _PyErr_NormalizeException(tstate, &exception, &v, &tb);
+ if (tb == NULL) {
+ tb = Py_None;
+ Py_INCREF(tb);
+ }
+ PyException_SetTraceback(v, tb);
+ if (exception == NULL) {
+ goto done;
+ }
+
+ /* Now we know v != NULL too */
+ if (set_sys_last_vars) {
+ if (_PySys_SetObjectId(&PyId_last_type, exception) < 0) {
+ _PyErr_Clear(tstate);
+ }
+ if (_PySys_SetObjectId(&PyId_last_value, v) < 0) {
+ _PyErr_Clear(tstate);
+ }
+ if (_PySys_SetObjectId(&PyId_last_traceback, tb) < 0) {
+ _PyErr_Clear(tstate);
+ }
+ }
+ hook = _PySys_GetObjectId(&PyId_excepthook);
+ if (_PySys_Audit(tstate, "sys.excepthook", "OOOO", hook ? hook : Py_None,
+ exception, v, tb) < 0) {
+ if (PyErr_ExceptionMatches(PyExc_RuntimeError)) {
+ PyErr_Clear();
+ goto done;
+ }
+ _PyErr_WriteUnraisableMsg("in audit hook", NULL);
+ }
+ if (hook) {
+ PyObject* stack[3];
+ PyObject *result;
+
+ stack[0] = exception;
+ stack[1] = v;
+ stack[2] = tb;
+ result = _PyObject_FastCall(hook, stack, 3);
+ if (result == NULL) {
+ handle_system_exit();
+
+ PyObject *exception2, *v2, *tb2;
+ _PyErr_Fetch(tstate, &exception2, &v2, &tb2);
+ _PyErr_NormalizeException(tstate, &exception2, &v2, &tb2);
+ /* It should not be possible for exception2 or v2
+ to be NULL. However PyErr_Display() can't
+ tolerate NULLs, so just be safe. */
+ if (exception2 == NULL) {
+ exception2 = Py_None;
+ Py_INCREF(exception2);
+ }
+ if (v2 == NULL) {
+ v2 = Py_None;
+ Py_INCREF(v2);
+ }
+ fflush(stdout);
+ PySys_WriteStderr("Error in sys.excepthook:\n");
+ PyErr_Display(exception2, v2, tb2);
+ PySys_WriteStderr("\nOriginal exception was:\n");
+ PyErr_Display(exception, v, tb);
+ Py_DECREF(exception2);
+ Py_DECREF(v2);
+ Py_XDECREF(tb2);
+ }
+ Py_XDECREF(result);
+ }
+ else {
+ PySys_WriteStderr("sys.excepthook is missing\n");
+ PyErr_Display(exception, v, tb);
+ }
+
+done:
+ Py_XDECREF(exception);
+ Py_XDECREF(v);
+ Py_XDECREF(tb);
+}
+
+void
+_PyErr_Print(PyThreadState *tstate)
+{
+ _PyErr_PrintEx(tstate, 1);
+}
+
+void
+PyErr_PrintEx(int set_sys_last_vars)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ _PyErr_PrintEx(tstate, set_sys_last_vars);
+}
+
+void
+PyErr_Print(void)
+{
+ PyErr_PrintEx(1);
+}
+
+static void
+print_exception(PyObject *f, PyObject *value)
+{
+ int err = 0;
+ PyObject *type, *tb;
+ _Py_IDENTIFIER(print_file_and_line);
+
+ if (!PyExceptionInstance_Check(value)) {
+ err = PyFile_WriteString("TypeError: print_exception(): Exception expected for value, ", f);
+ err += PyFile_WriteString(Py_TYPE(value)->tp_name, f);
+ err += PyFile_WriteString(" found\n", f);
+ if (err)
+ PyErr_Clear();
+ return;
+ }
+
+ Py_INCREF(value);
+ fflush(stdout);
+ type = (PyObject *) Py_TYPE(value);
+ tb = PyException_GetTraceback(value);
+ if (tb && tb != Py_None)
+ err = PyTraceBack_Print(tb, f);
+ if (err == 0 &&
+ _PyObject_HasAttrId(value, &PyId_print_file_and_line))
+ {
+ PyObject *message, *filename, *text;
+ Py_ssize_t lineno, offset;
+ if (!parse_syntax_error(value, &message, &filename,
+ &lineno, &offset, &text))
+ PyErr_Clear();
+ else {
+ PyObject *line;
+
+ Py_DECREF(value);
+ value = message;
+
+ line = PyUnicode_FromFormat(" File \"%S\", line %zd\n",
+ filename, lineno);
+ Py_DECREF(filename);
+ if (line != NULL) {
+ PyFile_WriteObject(line, f, Py_PRINT_RAW);
+ Py_DECREF(line);
+ }
+
+ if (text != NULL) {
+ print_error_text(f, offset, text);
+ Py_DECREF(text);
+ }
+
+ /* Can't be bothered to check all those
+ PyFile_WriteString() calls */
+ if (PyErr_Occurred())
+ err = -1;
+ }
+ }
+ if (err) {
+ /* Don't do anything else */
+ }
+ else {
+ PyObject* modulename;
+
+ _Py_IDENTIFIER(__module__);
+ assert(PyExceptionClass_Check(type));
+
+ modulename = _PyObject_GetAttrId(type, &PyId___module__);
+ if (modulename == NULL || !PyUnicode_Check(modulename))
+ {
+ Py_XDECREF(modulename);
+ PyErr_Clear();
+ err = PyFile_WriteString("<unknown>.", f);
+ }
+ else {
+ if (!_PyUnicode_EqualToASCIIId(modulename, &PyId_builtins))
+ {
+ err = PyFile_WriteObject(modulename, f, Py_PRINT_RAW);
+ err += PyFile_WriteString(".", f);
+ }
+ Py_DECREF(modulename);
+ }
+ if (err == 0) {
+ PyObject* qualname = _PyType_GetQualName((PyTypeObject *)type);
+ if (qualname == NULL || !PyUnicode_Check(qualname)) {
+ Py_XDECREF(qualname);
+ PyErr_Clear();
+ err = PyFile_WriteString("<unknown>", f);
+ }
+ else {
+ err = PyFile_WriteObject(qualname, f, Py_PRINT_RAW);
+ Py_DECREF(qualname);
+ }
+ }
+ }
+ if (err == 0 && (value != Py_None)) {
+ PyObject *s = PyObject_Str(value);
+ /* only print colon if the str() of the
+ object is not the empty string
+ */
+ if (s == NULL) {
+ PyErr_Clear();
+ err = -1;
+ PyFile_WriteString(": <exception str() failed>", f);
+ }
+ else if (!PyUnicode_Check(s) ||
+ PyUnicode_GetLength(s) != 0)
+ err = PyFile_WriteString(": ", f);
+ if (err == 0)
+ err = PyFile_WriteObject(s, f, Py_PRINT_RAW);
+ Py_XDECREF(s);
+ }
+ /* try to write a newline in any case */
+ if (err < 0) {
+ PyErr_Clear();
+ }
+ err += PyFile_WriteString("\n", f);
+ Py_XDECREF(tb);
+ Py_DECREF(value);
+ /* If an error happened here, don't show it.
+ XXX This is wrong, but too many callers rely on this behavior. */
+ if (err != 0)
+ PyErr_Clear();
+}
+
+static const char cause_message[] =
+ "\nThe above exception was the direct cause "
+ "of the following exception:\n\n";
+
+static const char context_message[] =
+ "\nDuring handling of the above exception, "
+ "another exception occurred:\n\n";
+
+static void
+print_exception_recursive(PyObject *f, PyObject *value, PyObject *seen)
+{
+ int err = 0, res;
+ PyObject *cause, *context;
+
+ if (seen != NULL) {
+ /* Exception chaining */
+ PyObject *value_id = PyLong_FromVoidPtr(value);
+ if (value_id == NULL || PySet_Add(seen, value_id) == -1)
+ PyErr_Clear();
+ else if (PyExceptionInstance_Check(value)) {
+ PyObject *check_id = NULL;
+ cause = PyException_GetCause(value);
+ context = PyException_GetContext(value);
+ if (cause) {
+ check_id = PyLong_FromVoidPtr(cause);
+ if (check_id == NULL) {
+ res = -1;
+ } else {
+ res = PySet_Contains(seen, check_id);
+ Py_DECREF(check_id);
+ }
+ if (res == -1)
+ PyErr_Clear();
+ if (res == 0) {
+ print_exception_recursive(
+ f, cause, seen);
+ err |= PyFile_WriteString(
+ cause_message, f);
+ }
+ }
+ else if (context &&
+ !((PyBaseExceptionObject *)value)->suppress_context) {
+ check_id = PyLong_FromVoidPtr(context);
+ if (check_id == NULL) {
+ res = -1;
+ } else {
+ res = PySet_Contains(seen, check_id);
+ Py_DECREF(check_id);
+ }
+ if (res == -1)
+ PyErr_Clear();
+ if (res == 0) {
+ print_exception_recursive(
+ f, context, seen);
+ err |= PyFile_WriteString(
+ context_message, f);
+ }
+ }
+ Py_XDECREF(context);
+ Py_XDECREF(cause);
+ }
+ Py_XDECREF(value_id);
+ }
+ print_exception(f, value);
+ if (err != 0)
+ PyErr_Clear();
+}
+
+void
+_PyErr_Display(PyObject *file, PyObject *exception, PyObject *value, PyObject *tb)
+{
+ assert(file != NULL && file != Py_None);
+
+ PyObject *seen;
+ if (PyExceptionInstance_Check(value)
+ && tb != NULL && PyTraceBack_Check(tb)) {
+ /* Put the traceback on the exception, otherwise it won't get
+ displayed. See issue #18776. */
+ PyObject *cur_tb = PyException_GetTraceback(value);
+ if (cur_tb == NULL)
+ PyException_SetTraceback(value, tb);
+ else
+ Py_DECREF(cur_tb);
+ }
+
+ /* We choose to ignore seen being possibly NULL, and report
+ at least the main exception (it could be a MemoryError).
+ */
+ seen = PySet_New(NULL);
+ if (seen == NULL) {
+ PyErr_Clear();
+ }
+ print_exception_recursive(file, value, seen);
+ Py_XDECREF(seen);
+
+ /* Call file.flush() */
+ PyObject *res = _PyObject_CallMethodIdNoArgs(file, &PyId_flush);
+ if (!res) {
+ /* Silently ignore file.flush() error */
+ PyErr_Clear();
+ }
+ else {
+ Py_DECREF(res);
+ }
+}
+
+void
+PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb)
+{
+ PyObject *file = _PySys_GetObjectId(&PyId_stderr);
+ if (file == NULL) {
+ _PyObject_Dump(value);
+ fprintf(stderr, "lost sys.stderr\n");
+ return;
+ }
+ if (file == Py_None) {
+ return;
+ }
+ Py_INCREF(file);
+ _PyErr_Display(file, exception, value, tb);
+ Py_DECREF(file);
+}
+
+PyObject *
+PyRun_StringFlags(const char *str, int start, PyObject *globals,
+ PyObject *locals, PyCompilerFlags *flags)
+{
+ PyObject *ret = NULL;
+ mod_ty mod;
+ PyArena *arena;
+ PyObject *filename;
+ int use_peg = _PyInterpreterState_GET()->config._use_peg_parser;
+
+ filename = _PyUnicode_FromId(&PyId_string); /* borrowed */
+ if (filename == NULL)
+ return NULL;
+
+ arena = PyArena_New();
+ if (arena == NULL)
+ return NULL;
+
+ if (use_peg) {
+ mod = PyPegen_ASTFromStringObject(str, filename, start, flags, arena);
+ }
+ else {
+ mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena);
+ }
+
+ if (mod != NULL)
+ ret = run_mod(mod, filename, globals, locals, flags, arena);
+ PyArena_Free(arena);
+ return ret;
+}
+
+
+static PyObject *
+pyrun_file(FILE *fp, PyObject *filename, int start, PyObject *globals,
+ PyObject *locals, int closeit, PyCompilerFlags *flags)
+{
+ PyArena *arena = PyArena_New();
+ if (arena == NULL) {
+ return NULL;
+ }
+
+ mod_ty mod;
+ int use_peg = _PyInterpreterState_GET()->config._use_peg_parser;
+ if (use_peg) {
+ mod = PyPegen_ASTFromFileObject(fp, filename, start, NULL, NULL, NULL,
+ flags, NULL, arena);
+ }
+ else {
+ mod = PyParser_ASTFromFileObject(fp, filename, NULL, start, 0, 0,
+ flags, NULL, arena);
+ }
+
+ if (closeit) {
+ fclose(fp);
+ }
+
+ PyObject *ret;
+ if (mod != NULL) {
+ ret = run_mod(mod, filename, globals, locals, flags, arena);
+ }
+ else {
+ ret = NULL;
+ }
+ PyArena_Free(arena);
+
+ return ret;
+}
+
+
+PyObject *
+PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals,
+ PyObject *locals, int closeit, PyCompilerFlags *flags)
+{
+ PyObject *filename_obj = PyUnicode_DecodeFSDefault(filename);
+ if (filename_obj == NULL) {
+ return NULL;
+ }
+
+ PyObject *res = pyrun_file(fp, filename_obj, start, globals,
+ locals, closeit, flags);
+ Py_DECREF(filename_obj);
+ return res;
+
+}
+
+
+static void
+flush_io(void)
+{
+ PyObject *f, *r;
+ PyObject *type, *value, *traceback;
+
+ /* Save the current exception */
+ PyErr_Fetch(&type, &value, &traceback);
+
+ f = _PySys_GetObjectId(&PyId_stderr);
+ if (f != NULL) {
+ r = _PyObject_CallMethodIdNoArgs(f, &PyId_flush);
+ if (r)
+ Py_DECREF(r);
+ else
+ PyErr_Clear();
+ }
+ f = _PySys_GetObjectId(&PyId_stdout);
+ if (f != NULL) {
+ r = _PyObject_CallMethodIdNoArgs(f, &PyId_flush);
+ if (r)
+ Py_DECREF(r);
+ else
+ PyErr_Clear();
+ }
+
+ PyErr_Restore(type, value, traceback);
+}
+
+static PyObject *
+run_eval_code_obj(PyThreadState *tstate, PyCodeObject *co, PyObject *globals, PyObject *locals)
+{
+ PyObject *v;
+ /*
+ * We explicitly re-initialize _Py_UnhandledKeyboardInterrupt every eval
+ * _just in case_ someone is calling into an embedded Python where they
+ * don't care about an uncaught KeyboardInterrupt exception (why didn't they
+ * leave config.install_signal_handlers set to 0?!?) but then later call
+ * Py_Main() itself (which _checks_ this flag and dies with a signal after
+ * its interpreter exits). We don't want a previous embedded interpreter's
+ * uncaught exception to trigger an unexplained signal exit from a future
+ * Py_Main() based one.
+ */
+ _Py_UnhandledKeyboardInterrupt = 0;
+
+ /* Set globals['__builtins__'] if it doesn't exist */
+ if (globals != NULL && PyDict_GetItemString(globals, "__builtins__") == NULL) {
+ if (PyDict_SetItemString(globals, "__builtins__",
+ tstate->interp->builtins) < 0) {
+ return NULL;
+ }
+ }
+
+ v = PyEval_EvalCode((PyObject*)co, globals, locals);
+ if (!v && _PyErr_Occurred(tstate) == PyExc_KeyboardInterrupt) {
+ _Py_UnhandledKeyboardInterrupt = 1;
+ }
+ return v;
+}
+
+static PyObject *
+run_mod(mod_ty mod, PyObject *filename, PyObject *globals, PyObject *locals,
+ PyCompilerFlags *flags, PyArena *arena)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyCodeObject *co = PyAST_CompileObject(mod, filename, flags, -1, arena);
+ if (co == NULL)
+ return NULL;
+
+ if (_PySys_Audit(tstate, "exec", "O", co) < 0) {
+ Py_DECREF(co);
+ return NULL;
+ }
+
+ PyObject *v = run_eval_code_obj(tstate, co, globals, locals);
+ Py_DECREF(co);
+ return v;
+}
+
+static PyObject *
+run_pyc_file(FILE *fp, PyObject *globals, PyObject *locals,
+ PyCompilerFlags *flags)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyCodeObject *co;
+ PyObject *v;
+ long magic;
+ long PyImport_GetMagicNumber(void);
+
+ magic = PyMarshal_ReadLongFromFile(fp);
+ if (magic != PyImport_GetMagicNumber()) {
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_RuntimeError,
+ "Bad magic number in .pyc file");
+ goto error;
+ }
+ /* Skip the rest of the header. */
+ (void) PyMarshal_ReadLongFromFile(fp);
+ (void) PyMarshal_ReadLongFromFile(fp);
+ (void) PyMarshal_ReadLongFromFile(fp);
+ if (PyErr_Occurred()) {
+ goto error;
+ }
+ v = PyMarshal_ReadLastObjectFromFile(fp);
+ if (v == NULL || !PyCode_Check(v)) {
+ Py_XDECREF(v);
+ PyErr_SetString(PyExc_RuntimeError,
+ "Bad code object in .pyc file");
+ goto error;
+ }
+ fclose(fp);
+ co = (PyCodeObject *)v;
+ v = run_eval_code_obj(tstate, co, globals, locals);
+ if (v && flags)
+ flags->cf_flags |= (co->co_flags & PyCF_MASK);
+ Py_DECREF(co);
+ return v;
+error:
+ fclose(fp);
+ return NULL;
+}
+
+PyObject *
+Py_CompileStringObject(const char *str, PyObject *filename, int start,
+ PyCompilerFlags *flags, int optimize)
+{
+ PyCodeObject *co;
+ mod_ty mod;
+ int use_peg = _PyInterpreterState_GET()->config._use_peg_parser;
+ PyArena *arena = PyArena_New();
+ if (arena == NULL)
+ return NULL;
+
+ if (use_peg) {
+ mod = PyPegen_ASTFromStringObject(str, filename, start, flags, arena);
+ }
+ else {
+ mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena);
+ }
+ if (mod == NULL) {
+ PyArena_Free(arena);
+ return NULL;
+ }
+ if (flags && (flags->cf_flags & PyCF_ONLY_AST)) {
+ PyObject *result = PyAST_mod2obj(mod);
+ PyArena_Free(arena);
+ return result;
+ }
+ co = PyAST_CompileObject(mod, filename, flags, optimize, arena);
+ PyArena_Free(arena);
+ return (PyObject *)co;
+}
+
+PyObject *
+Py_CompileStringExFlags(const char *str, const char *filename_str, int start,
+ PyCompilerFlags *flags, int optimize)
+{
+ PyObject *filename, *co;
+ filename = PyUnicode_DecodeFSDefault(filename_str);
+ if (filename == NULL)
+ return NULL;
+ co = Py_CompileStringObject(str, filename, start, flags, optimize);
+ Py_DECREF(filename);
+ return co;
+}
+
+/* For use in Py_LIMITED_API */
+#undef Py_CompileString
+PyObject *
+PyCompileString(const char *str, const char *filename, int start)
+{
+ return Py_CompileStringFlags(str, filename, start, NULL);
+}
+
+const char *
+_Py_SourceAsString(PyObject *cmd, const char *funcname, const char *what, PyCompilerFlags *cf, PyObject **cmd_copy)
+{
+ const char *str;
+ Py_ssize_t size;
+ Py_buffer view;
+
+ *cmd_copy = NULL;
+ if (PyUnicode_Check(cmd)) {
+ cf->cf_flags |= PyCF_IGNORE_COOKIE;
+ str = PyUnicode_AsUTF8AndSize(cmd, &size);
+ if (str == NULL)
+ return NULL;
+ }
+ else if (PyBytes_Check(cmd)) {
+ str = PyBytes_AS_STRING(cmd);
+ size = PyBytes_GET_SIZE(cmd);
+ }
+ else if (PyByteArray_Check(cmd)) {
+ str = PyByteArray_AS_STRING(cmd);
+ size = PyByteArray_GET_SIZE(cmd);
+ }
+ else if (PyObject_GetBuffer(cmd, &view, PyBUF_SIMPLE) == 0) {
+ /* Copy to NUL-terminated buffer. */
+ *cmd_copy = PyBytes_FromStringAndSize(
+ (const char *)view.buf, view.len);
+ PyBuffer_Release(&view);
+ if (*cmd_copy == NULL) {
+ return NULL;
+ }
+ str = PyBytes_AS_STRING(*cmd_copy);
+ size = PyBytes_GET_SIZE(*cmd_copy);
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "%s() arg 1 must be a %s object",
+ funcname, what);
+ return NULL;
+ }
+
+ if (strlen(str) != (size_t)size) {
+ PyErr_SetString(PyExc_ValueError,
+ "source code string cannot contain null bytes");
+ Py_CLEAR(*cmd_copy);
+ return NULL;
+ }
+ return str;
+}
+
+struct symtable *
+Py_SymtableStringObject(const char *str, PyObject *filename, int start)
+{
+ PyCompilerFlags flags = _PyCompilerFlags_INIT;
+ return _Py_SymtableStringObjectFlags(str, filename, start, &flags);
+}
+
+struct symtable *
+_Py_SymtableStringObjectFlags(const char *str, PyObject *filename, int start, PyCompilerFlags *flags)
+{
+ struct symtable *st;
+ mod_ty mod;
+ int use_peg = _PyInterpreterState_GET()->config._use_peg_parser;
+ PyArena *arena;
+
+ arena = PyArena_New();
+ if (arena == NULL)
+ return NULL;
+
+ if (use_peg) {
+ mod = PyPegen_ASTFromStringObject(str, filename, start, flags, arena);
+ }
+ else {
+ mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena);
+ }
+ if (mod == NULL) {
+ PyArena_Free(arena);
+ return NULL;
+ }
+ st = PySymtable_BuildObject(mod, filename, 0);
+ PyArena_Free(arena);
+ return st;
+}
+
+struct symtable *
+Py_SymtableString(const char *str, const char *filename_str, int start)
+{
+ PyObject *filename;
+ struct symtable *st;
+
+ filename = PyUnicode_DecodeFSDefault(filename_str);
+ if (filename == NULL)
+ return NULL;
+ st = Py_SymtableStringObject(str, filename, start);
+ Py_DECREF(filename);
+ return st;
+}
+
+/* Preferred access to parser is through AST. */
+mod_ty
+PyParser_ASTFromStringObject(const char *s, PyObject *filename, int start,
+ PyCompilerFlags *flags, PyArena *arena)
+{
+ mod_ty mod;
+ PyCompilerFlags localflags = _PyCompilerFlags_INIT;
+ perrdetail err;
+ int iflags = PARSER_FLAGS(flags);
+ if (flags && (flags->cf_flags & PyCF_ONLY_AST) && flags->cf_feature_version < 7)
+ iflags |= PyPARSE_ASYNC_HACKS;
+
+ node *n = PyParser_ParseStringObject(s, filename,
+ &_PyParser_Grammar, start, &err,
+ &iflags);
+ if (flags == NULL) {
+ flags = &localflags;
+ }
+ if (n) {
+ flags->cf_flags |= iflags & PyCF_MASK;
+ mod = PyAST_FromNodeObject(n, flags, filename, arena);
+ PyNode_Free(n);
+ }
+ else {
+ err_input(&err);
+ mod = NULL;
+ }
+ err_free(&err);
+ return mod;
+}
+
+mod_ty
+PyParser_ASTFromString(const char *s, const char *filename_str, int start,
+ PyCompilerFlags *flags, PyArena *arena)
+{
+ PyObject *filename;
+ mod_ty mod;
+ filename = PyUnicode_DecodeFSDefault(filename_str);
+ if (filename == NULL)
+ return NULL;
+ mod = PyParser_ASTFromStringObject(s, filename, start, flags, arena);
+ Py_DECREF(filename);
+ return mod;
+}
+
+mod_ty
+PyParser_ASTFromFileObject(FILE *fp, PyObject *filename, const char* enc,
+ int start, const char *ps1,
+ const char *ps2, PyCompilerFlags *flags, int *errcode,
+ PyArena *arena)
+{
+ mod_ty mod;
+ PyCompilerFlags localflags = _PyCompilerFlags_INIT;
+ perrdetail err;
+ int iflags = PARSER_FLAGS(flags);
+
+ node *n = PyParser_ParseFileObject(fp, filename, enc,
+ &_PyParser_Grammar,
+ start, ps1, ps2, &err, &iflags);
+ if (flags == NULL) {
+ flags = &localflags;
+ }
+ if (n) {
+ flags->cf_flags |= iflags & PyCF_MASK;
+ mod = PyAST_FromNodeObject(n, flags, filename, arena);
+ PyNode_Free(n);
+ }
+ else {
+ err_input(&err);
+ if (errcode)
+ *errcode = err.error;
+ mod = NULL;
+ }
+ err_free(&err);
+ return mod;
+}
+
+mod_ty
+PyParser_ASTFromFile(FILE *fp, const char *filename_str, const char* enc,
+ int start, const char *ps1,
+ const char *ps2, PyCompilerFlags *flags, int *errcode,
+ PyArena *arena)
+{
+ mod_ty mod;
+ PyObject *filename;
+ filename = PyUnicode_DecodeFSDefault(filename_str);
+ if (filename == NULL)
+ return NULL;
+ mod = PyParser_ASTFromFileObject(fp, filename, enc, start, ps1, ps2,
+ flags, errcode, arena);
+ Py_DECREF(filename);
+ return mod;
+}
+
+/* Simplified interface to parsefile -- return node or set exception */
+
+node *
+PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int flags)
+{
+ perrdetail err;
+ node *n = PyParser_ParseFileFlags(fp, filename, NULL,
+ &_PyParser_Grammar,
+ start, NULL, NULL, &err, flags);
+ if (n == NULL)
+ err_input(&err);
+ err_free(&err);
+
+ return n;
+}
+
+/* Simplified interface to parsestring -- return node or set exception */
+
+node *
+PyParser_SimpleParseStringFlags(const char *str, int start, int flags)
+{
+ perrdetail err;
+ node *n = PyParser_ParseStringFlags(str, &_PyParser_Grammar,
+ start, &err, flags);
+ if (n == NULL)
+ err_input(&err);
+ err_free(&err);
+ return n;
+}
+
+node *
+PyParser_SimpleParseStringFlagsFilename(const char *str, const char *filename,
+ int start, int flags)
+{
+ perrdetail err;
+ node *n = PyParser_ParseStringFlagsFilename(str, filename,
+ &_PyParser_Grammar, start, &err, flags);
+ if (n == NULL)
+ err_input(&err);
+ err_free(&err);
+ return n;
+}
+
+/* May want to move a more generalized form of this to parsetok.c or
+ even parser modules. */
+
+void
+PyParser_ClearError(perrdetail *err)
+{
+ err_free(err);
+}
+
+void
+PyParser_SetError(perrdetail *err)
+{
+ err_input(err);
+}
+
+static void
+err_free(perrdetail *err)
+{
+ Py_CLEAR(err->filename);
+}
+
+/* Set the error appropriate to the given input error code (see errcode.h) */
+
+static void
+err_input(perrdetail *err)
+{
+ PyObject *v, *w, *errtype, *errtext;
+ PyObject *msg_obj = NULL;
+ const char *msg = NULL;
+ int offset = err->offset;
+
+ errtype = PyExc_SyntaxError;
+ switch (err->error) {
+ case E_ERROR:
+ goto cleanup;
+ case E_SYNTAX:
+ errtype = PyExc_IndentationError;
+ if (err->expected == INDENT)
+ msg = "expected an indented block";
+ else if (err->token == INDENT)
+ msg = "unexpected indent";
+ else if (err->token == DEDENT)
+ msg = "unexpected unindent";
+ else if (err->expected == NOTEQUAL) {
+ errtype = PyExc_SyntaxError;
+ msg = "with Barry as BDFL, use '<>' instead of '!='";
+ }
+ else {
+ errtype = PyExc_SyntaxError;
+ msg = "invalid syntax";
+ }
+ break;
+ case E_TOKEN:
+ msg = "invalid token";
+ break;
+ case E_EOFS:
+ msg = "EOF while scanning triple-quoted string literal";
+ break;
+ case E_EOLS:
+ msg = "EOL while scanning string literal";
+ break;
+ case E_INTR:
+ if (!PyErr_Occurred())
+ PyErr_SetNone(PyExc_KeyboardInterrupt);
+ goto cleanup;
+ case E_NOMEM:
+ PyErr_NoMemory();
+ goto cleanup;
+ case E_EOF:
+ msg = "unexpected EOF while parsing";
+ break;
+ case E_TABSPACE:
+ errtype = PyExc_TabError;
+ msg = "inconsistent use of tabs and spaces in indentation";
+ break;
+ case E_OVERFLOW:
+ msg = "expression too long";
+ break;
+ case E_DEDENT:
+ errtype = PyExc_IndentationError;
+ msg = "unindent does not match any outer indentation level";
+ break;
+ case E_TOODEEP:
+ errtype = PyExc_IndentationError;
+ msg = "too many levels of indentation";
+ break;
+ case E_DECODE: {
+ PyObject *type, *value, *tb;
+ PyErr_Fetch(&type, &value, &tb);
+ msg = "unknown decode error";
+ if (value != NULL)
+ msg_obj = PyObject_Str(value);
+ Py_XDECREF(type);
+ Py_XDECREF(value);
+ Py_XDECREF(tb);
+ break;
+ }
+ case E_LINECONT:
+ msg = "unexpected character after line continuation character";
+ break;
+
+ case E_BADSINGLE:
+ msg = "multiple statements found while compiling a single statement";
+ break;
+ default:
+ fprintf(stderr, "error=%d\n", err->error);
+ msg = "unknown parsing error";
+ break;
+ }
+ /* err->text may not be UTF-8 in case of decoding errors.
+ Explicitly convert to an object. */
+ if (!err->text) {
+ errtext = Py_None;
+ Py_INCREF(Py_None);
+ } else {
+ errtext = PyUnicode_DecodeUTF8(err->text, err->offset,
+ "replace");
+ if (errtext != NULL) {
+ Py_ssize_t len = strlen(err->text);
+ offset = (int)PyUnicode_GET_LENGTH(errtext);
+ if (len != err->offset) {
+ Py_DECREF(errtext);
+ errtext = PyUnicode_DecodeUTF8(err->text, len,
+ "replace");
+ }
+ }
+ }
+ v = Py_BuildValue("(OiiN)", err->filename,
+ err->lineno, offset, errtext);
+ if (v != NULL) {
+ if (msg_obj)
+ w = Py_BuildValue("(OO)", msg_obj, v);
+ else
+ w = Py_BuildValue("(sO)", msg, v);
+ } else
+ w = NULL;
+ Py_XDECREF(v);
+ PyErr_SetObject(errtype, w);
+ Py_XDECREF(w);
+cleanup:
+ Py_XDECREF(msg_obj);
+ if (err->text != NULL) {
+ PyObject_FREE(err->text);
+ err->text = NULL;
+ }
+}
+
+
+#if defined(USE_STACKCHECK)
+#if defined(WIN32) && defined(_MSC_VER)
+
+/* Stack checking for Microsoft C */
+
+#include <malloc.h>
+#include <excpt.h>
+
+/*
+ * Return non-zero when we run out of memory on the stack; zero otherwise.
+ */
+int
+PyOS_CheckStack(void)
+{
+ __try {
+ /* alloca throws a stack overflow exception if there's
+ not enough space left on the stack */
+ alloca(PYOS_STACK_MARGIN * sizeof(void*));
+ return 0;
+ } __except (GetExceptionCode() == STATUS_STACK_OVERFLOW ?
+ EXCEPTION_EXECUTE_HANDLER :
+ EXCEPTION_CONTINUE_SEARCH) {
+ int errcode = _resetstkoflw();
+ if (errcode == 0)
+ {
+ Py_FatalError("Could not reset the stack!");
+ }
+ }
+ return 1;
+}
+
+#endif /* WIN32 && _MSC_VER */
+
+/* Alternate implementations can be added here... */
+
+#endif /* USE_STACKCHECK */
+
+/* Deprecated C API functions still provided for binary compatibility */
+
+#undef PyParser_SimpleParseFile
+PyAPI_FUNC(node *)
+PyParser_SimpleParseFile(FILE *fp, const char *filename, int start)
+{
+ return PyParser_SimpleParseFileFlags(fp, filename, start, 0);
+}
+
+#undef PyParser_SimpleParseString
+PyAPI_FUNC(node *)
+PyParser_SimpleParseString(const char *str, int start)
+{
+ return PyParser_SimpleParseStringFlags(str, start, 0);
+}
+
+#undef PyRun_AnyFile
+PyAPI_FUNC(int)
+PyRun_AnyFile(FILE *fp, const char *name)
+{
+ return PyRun_AnyFileExFlags(fp, name, 0, NULL);
+}
+
+#undef PyRun_AnyFileEx
+PyAPI_FUNC(int)
+PyRun_AnyFileEx(FILE *fp, const char *name, int closeit)
+{
+ return PyRun_AnyFileExFlags(fp, name, closeit, NULL);
+}
+
+#undef PyRun_AnyFileFlags
+PyAPI_FUNC(int)
+PyRun_AnyFileFlags(FILE *fp, const char *name, PyCompilerFlags *flags)
+{
+ return PyRun_AnyFileExFlags(fp, name, 0, flags);
+}
+
+#undef PyRun_File
+PyAPI_FUNC(PyObject *)
+PyRun_File(FILE *fp, const char *p, int s, PyObject *g, PyObject *l)
+{
+ return PyRun_FileExFlags(fp, p, s, g, l, 0, NULL);
+}
+
+#undef PyRun_FileEx
+PyAPI_FUNC(PyObject *)
+PyRun_FileEx(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, int c)
+{
+ return PyRun_FileExFlags(fp, p, s, g, l, c, NULL);
+}
+
+#undef PyRun_FileFlags
+PyAPI_FUNC(PyObject *)
+PyRun_FileFlags(FILE *fp, const char *p, int s, PyObject *g, PyObject *l,
+ PyCompilerFlags *flags)
+{
+ return PyRun_FileExFlags(fp, p, s, g, l, 0, flags);
+}
+
+#undef PyRun_SimpleFile
+PyAPI_FUNC(int)
+PyRun_SimpleFile(FILE *f, const char *p)
+{
+ return PyRun_SimpleFileExFlags(f, p, 0, NULL);
+}
+
+#undef PyRun_SimpleFileEx
+PyAPI_FUNC(int)
+PyRun_SimpleFileEx(FILE *f, const char *p, int c)
+{
+ return PyRun_SimpleFileExFlags(f, p, c, NULL);
+}
+
+
+#undef PyRun_String
+PyAPI_FUNC(PyObject *)
+PyRun_String(const char *str, int s, PyObject *g, PyObject *l)
+{
+ return PyRun_StringFlags(str, s, g, l, NULL);
+}
+
+#undef PyRun_SimpleString
+PyAPI_FUNC(int)
+PyRun_SimpleString(const char *s)
+{
+ return PyRun_SimpleStringFlags(s, NULL);
+}
+
+#undef Py_CompileString
+PyAPI_FUNC(PyObject *)
+Py_CompileString(const char *str, const char *p, int s)
+{
+ return Py_CompileStringExFlags(str, p, s, NULL, -1);
+}
+
+#undef Py_CompileStringFlags
+PyAPI_FUNC(PyObject *)
+Py_CompileStringFlags(const char *str, const char *p, int s,
+ PyCompilerFlags *flags)
+{
+ return Py_CompileStringExFlags(str, p, s, flags, -1);
+}
+
+#undef PyRun_InteractiveOne
+PyAPI_FUNC(int)
+PyRun_InteractiveOne(FILE *f, const char *p)
+{
+ return PyRun_InteractiveOneFlags(f, p, NULL);
+}
+
+#undef PyRun_InteractiveLoop
+PyAPI_FUNC(int)
+PyRun_InteractiveLoop(FILE *f, const char *p)
+{
+ return PyRun_InteractiveLoopFlags(f, p, NULL);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/contrib/tools/python3/src/Python/pytime.c b/contrib/tools/python3/src/Python/pytime.c
new file mode 100644
index 00000000000..a9af7572431
--- /dev/null
+++ b/contrib/tools/python3/src/Python/pytime.c
@@ -0,0 +1,1135 @@
+#include "Python.h"
+#ifdef MS_WINDOWS
+#include <winsock2.h> /* struct timeval */
+#endif
+
+#if defined(__APPLE__)
+#include <mach/mach_time.h> /* mach_absolute_time(), mach_timebase_info() */
+
+#if defined(__APPLE__) && defined(__has_builtin)
+# if __has_builtin(__builtin_available)
+# define HAVE_CLOCK_GETTIME_RUNTIME __builtin_available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)
+# endif
+#endif
+#endif
+
+#define _PyTime_check_mul_overflow(a, b) \
+ (assert(b > 0), \
+ (_PyTime_t)(a) < _PyTime_MIN / (_PyTime_t)(b) \
+ || _PyTime_MAX / (_PyTime_t)(b) < (_PyTime_t)(a))
+
+/* To millisecond (10^-3) */
+#define SEC_TO_MS 1000
+
+/* To microseconds (10^-6) */
+#define MS_TO_US 1000
+#define SEC_TO_US (SEC_TO_MS * MS_TO_US)
+
+/* To nanoseconds (10^-9) */
+#define US_TO_NS 1000
+#define MS_TO_NS (MS_TO_US * US_TO_NS)
+#define SEC_TO_NS (SEC_TO_MS * MS_TO_NS)
+
+/* Conversion from nanoseconds */
+#define NS_TO_MS (1000 * 1000)
+#define NS_TO_US (1000)
+
+static void
+error_time_t_overflow(void)
+{
+ PyErr_SetString(PyExc_OverflowError,
+ "timestamp out of range for platform time_t");
+}
+
+static void
+_PyTime_overflow(void)
+{
+ PyErr_SetString(PyExc_OverflowError,
+ "timestamp too large to convert to C _PyTime_t");
+}
+
+
+_PyTime_t
+_PyTime_MulDiv(_PyTime_t ticks, _PyTime_t mul, _PyTime_t div)
+{
+ _PyTime_t intpart, remaining;
+ /* Compute (ticks * mul / div) in two parts to prevent integer overflow:
+ compute integer part, and then the remaining part.
+
+ (ticks * mul) / div == (ticks / div) * mul + (ticks % div) * mul / div
+
+ The caller must ensure that "(div - 1) * mul" cannot overflow. */
+ intpart = ticks / div;
+ ticks %= div;
+ remaining = ticks * mul;
+ remaining /= div;
+ return intpart * mul + remaining;
+}
+
+
+time_t
+_PyLong_AsTime_t(PyObject *obj)
+{
+#if SIZEOF_TIME_T == SIZEOF_LONG_LONG
+ long long val;
+ val = PyLong_AsLongLong(obj);
+#else
+ long val;
+ Py_BUILD_ASSERT(sizeof(time_t) <= sizeof(long));
+ val = PyLong_AsLong(obj);
+#endif
+ if (val == -1 && PyErr_Occurred()) {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
+ error_time_t_overflow();
+ }
+ return -1;
+ }
+ return (time_t)val;
+}
+
+PyObject *
+_PyLong_FromTime_t(time_t t)
+{
+#if SIZEOF_TIME_T == SIZEOF_LONG_LONG
+ return PyLong_FromLongLong((long long)t);
+#else
+ Py_BUILD_ASSERT(sizeof(time_t) <= sizeof(long));
+ return PyLong_FromLong((long)t);
+#endif
+}
+
+/* Round to nearest with ties going to nearest even integer
+ (_PyTime_ROUND_HALF_EVEN) */
+static double
+_PyTime_RoundHalfEven(double x)
+{
+ double rounded = round(x);
+ if (fabs(x-rounded) == 0.5) {
+ /* halfway case: round to even */
+ rounded = 2.0*round(x/2.0);
+ }
+ return rounded;
+}
+
+static double
+_PyTime_Round(double x, _PyTime_round_t round)
+{
+ /* volatile avoids optimization changing how numbers are rounded */
+ volatile double d;
+
+ d = x;
+ if (round == _PyTime_ROUND_HALF_EVEN) {
+ d = _PyTime_RoundHalfEven(d);
+ }
+ else if (round == _PyTime_ROUND_CEILING) {
+ d = ceil(d);
+ }
+ else if (round == _PyTime_ROUND_FLOOR) {
+ d = floor(d);
+ }
+ else {
+ assert(round == _PyTime_ROUND_UP);
+ d = (d >= 0.0) ? ceil(d) : floor(d);
+ }
+ return d;
+}
+
+static int
+_PyTime_DoubleToDenominator(double d, time_t *sec, long *numerator,
+ long idenominator, _PyTime_round_t round)
+{
+ double denominator = (double)idenominator;
+ double intpart;
+ /* volatile avoids optimization changing how numbers are rounded */
+ volatile double floatpart;
+
+ floatpart = modf(d, &intpart);
+
+ floatpart *= denominator;
+ floatpart = _PyTime_Round(floatpart, round);
+ if (floatpart >= denominator) {
+ floatpart -= denominator;
+ intpart += 1.0;
+ }
+ else if (floatpart < 0) {
+ floatpart += denominator;
+ intpart -= 1.0;
+ }
+ assert(0.0 <= floatpart && floatpart < denominator);
+
+ if (!_Py_InIntegralTypeRange(time_t, intpart)) {
+ error_time_t_overflow();
+ return -1;
+ }
+ *sec = (time_t)intpart;
+ *numerator = (long)floatpart;
+ assert(0 <= *numerator && *numerator < idenominator);
+ return 0;
+}
+
+static int
+_PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator,
+ long denominator, _PyTime_round_t round)
+{
+ assert(denominator >= 1);
+
+ if (PyFloat_Check(obj)) {
+ double d = PyFloat_AsDouble(obj);
+ if (Py_IS_NAN(d)) {
+ *numerator = 0;
+ PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)");
+ return -1;
+ }
+ return _PyTime_DoubleToDenominator(d, sec, numerator,
+ denominator, round);
+ }
+ else {
+ *sec = _PyLong_AsTime_t(obj);
+ *numerator = 0;
+ if (*sec == (time_t)-1 && PyErr_Occurred()) {
+ return -1;
+ }
+ return 0;
+ }
+}
+
+int
+_PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
+{
+ if (PyFloat_Check(obj)) {
+ double intpart;
+ /* volatile avoids optimization changing how numbers are rounded */
+ volatile double d;
+
+ d = PyFloat_AsDouble(obj);
+ if (Py_IS_NAN(d)) {
+ PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)");
+ return -1;
+ }
+
+ d = _PyTime_Round(d, round);
+ (void)modf(d, &intpart);
+
+ if (!_Py_InIntegralTypeRange(time_t, intpart)) {
+ error_time_t_overflow();
+ return -1;
+ }
+ *sec = (time_t)intpart;
+ return 0;
+ }
+ else {
+ *sec = _PyLong_AsTime_t(obj);
+ if (*sec == (time_t)-1 && PyErr_Occurred()) {
+ return -1;
+ }
+ return 0;
+ }
+}
+
+int
+_PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec,
+ _PyTime_round_t round)
+{
+ return _PyTime_ObjectToDenominator(obj, sec, nsec, SEC_TO_NS, round);
+}
+
+int
+_PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec,
+ _PyTime_round_t round)
+{
+ return _PyTime_ObjectToDenominator(obj, sec, usec, SEC_TO_US, round);
+}
+
+_PyTime_t
+_PyTime_FromSeconds(int seconds)
+{
+ _PyTime_t t;
+ /* ensure that integer overflow cannot happen, int type should have 32
+ bits, whereas _PyTime_t type has at least 64 bits (SEC_TO_MS takes 30
+ bits). */
+ Py_BUILD_ASSERT(INT_MAX <= _PyTime_MAX / SEC_TO_NS);
+ Py_BUILD_ASSERT(INT_MIN >= _PyTime_MIN / SEC_TO_NS);
+
+ t = (_PyTime_t)seconds;
+ assert((t >= 0 && t <= _PyTime_MAX / SEC_TO_NS)
+ || (t < 0 && t >= _PyTime_MIN / SEC_TO_NS));
+ t *= SEC_TO_NS;
+ return t;
+}
+
+_PyTime_t
+_PyTime_FromNanoseconds(_PyTime_t ns)
+{
+ /* _PyTime_t already uses nanosecond resolution, no conversion needed */
+ return ns;
+}
+
+int
+_PyTime_FromNanosecondsObject(_PyTime_t *tp, PyObject *obj)
+{
+ long long nsec;
+ _PyTime_t t;
+
+ if (!PyLong_Check(obj)) {
+ PyErr_Format(PyExc_TypeError, "expect int, got %s",
+ Py_TYPE(obj)->tp_name);
+ return -1;
+ }
+
+ Py_BUILD_ASSERT(sizeof(long long) == sizeof(_PyTime_t));
+ nsec = PyLong_AsLongLong(obj);
+ if (nsec == -1 && PyErr_Occurred()) {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
+ _PyTime_overflow();
+ }
+ return -1;
+ }
+
+ /* _PyTime_t already uses nanosecond resolution, no conversion needed */
+ t = (_PyTime_t)nsec;
+ *tp = t;
+ return 0;
+}
+
+#ifdef HAVE_CLOCK_GETTIME
+static int
+pytime_fromtimespec(_PyTime_t *tp, struct timespec *ts, int raise)
+{
+ _PyTime_t t, nsec;
+ int res = 0;
+
+ Py_BUILD_ASSERT(sizeof(ts->tv_sec) <= sizeof(_PyTime_t));
+ t = (_PyTime_t)ts->tv_sec;
+
+ if (_PyTime_check_mul_overflow(t, SEC_TO_NS)) {
+ if (raise) {
+ _PyTime_overflow();
+ }
+ res = -1;
+ t = (t > 0) ? _PyTime_MAX : _PyTime_MIN;
+ }
+ else {
+ t = t * SEC_TO_NS;
+ }
+
+ nsec = ts->tv_nsec;
+ /* The following test is written for positive only nsec */
+ assert(nsec >= 0);
+ if (t > _PyTime_MAX - nsec) {
+ if (raise) {
+ _PyTime_overflow();
+ }
+ res = -1;
+ t = _PyTime_MAX;
+ }
+ else {
+ t += nsec;
+ }
+
+ *tp = t;
+ return res;
+}
+
+int
+_PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts)
+{
+ return pytime_fromtimespec(tp, ts, 1);
+}
+#endif
+
+#if !defined(MS_WINDOWS)
+static int
+pytime_fromtimeval(_PyTime_t *tp, struct timeval *tv, int raise)
+{
+ _PyTime_t t, usec;
+ int res = 0;
+
+ Py_BUILD_ASSERT(sizeof(tv->tv_sec) <= sizeof(_PyTime_t));
+ t = (_PyTime_t)tv->tv_sec;
+
+ if (_PyTime_check_mul_overflow(t, SEC_TO_NS)) {
+ if (raise) {
+ _PyTime_overflow();
+ }
+ res = -1;
+ t = (t > 0) ? _PyTime_MAX : _PyTime_MIN;
+ }
+ else {
+ t = t * SEC_TO_NS;
+ }
+
+ usec = (_PyTime_t)tv->tv_usec * US_TO_NS;
+ /* The following test is written for positive only usec */
+ assert(usec >= 0);
+ if (t > _PyTime_MAX - usec) {
+ if (raise) {
+ _PyTime_overflow();
+ }
+ res = -1;
+ t = _PyTime_MAX;
+ }
+ else {
+ t += usec;
+ }
+
+ *tp = t;
+ return res;
+}
+
+int
+_PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv)
+{
+ return pytime_fromtimeval(tp, tv, 1);
+}
+#endif
+
+static int
+_PyTime_FromDouble(_PyTime_t *t, double value, _PyTime_round_t round,
+ long unit_to_ns)
+{
+ /* volatile avoids optimization changing how numbers are rounded */
+ volatile double d;
+
+ /* convert to a number of nanoseconds */
+ d = value;
+ d *= (double)unit_to_ns;
+ d = _PyTime_Round(d, round);
+
+ if (!_Py_InIntegralTypeRange(_PyTime_t, d)) {
+ _PyTime_overflow();
+ return -1;
+ }
+ *t = (_PyTime_t)d;
+ return 0;
+}
+
+static int
+_PyTime_FromObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round,
+ long unit_to_ns)
+{
+ if (PyFloat_Check(obj)) {
+ double d;
+ d = PyFloat_AsDouble(obj);
+ if (Py_IS_NAN(d)) {
+ PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)");
+ return -1;
+ }
+ return _PyTime_FromDouble(t, d, round, unit_to_ns);
+ }
+ else {
+ long long sec;
+ Py_BUILD_ASSERT(sizeof(long long) <= sizeof(_PyTime_t));
+
+ sec = PyLong_AsLongLong(obj);
+ if (sec == -1 && PyErr_Occurred()) {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
+ _PyTime_overflow();
+ }
+ return -1;
+ }
+
+ if (_PyTime_check_mul_overflow(sec, unit_to_ns)) {
+ _PyTime_overflow();
+ return -1;
+ }
+ *t = sec * unit_to_ns;
+ return 0;
+ }
+}
+
+int
+_PyTime_FromSecondsObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round)
+{
+ return _PyTime_FromObject(t, obj, round, SEC_TO_NS);
+}
+
+int
+_PyTime_FromMillisecondsObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round)
+{
+ return _PyTime_FromObject(t, obj, round, MS_TO_NS);
+}
+
+double
+_PyTime_AsSecondsDouble(_PyTime_t t)
+{
+ /* volatile avoids optimization changing how numbers are rounded */
+ volatile double d;
+
+ if (t % SEC_TO_NS == 0) {
+ _PyTime_t secs;
+ /* Divide using integers to avoid rounding issues on the integer part.
+ 1e-9 cannot be stored exactly in IEEE 64-bit. */
+ secs = t / SEC_TO_NS;
+ d = (double)secs;
+ }
+ else {
+ d = (double)t;
+ d /= 1e9;
+ }
+ return d;
+}
+
+PyObject *
+_PyTime_AsNanosecondsObject(_PyTime_t t)
+{
+ Py_BUILD_ASSERT(sizeof(long long) >= sizeof(_PyTime_t));
+ return PyLong_FromLongLong((long long)t);
+}
+
+static _PyTime_t
+_PyTime_Divide(const _PyTime_t t, const _PyTime_t k,
+ const _PyTime_round_t round)
+{
+ assert(k > 1);
+ if (round == _PyTime_ROUND_HALF_EVEN) {
+ _PyTime_t x, r, abs_r;
+ x = t / k;
+ r = t % k;
+ abs_r = Py_ABS(r);
+ if (abs_r > k / 2 || (abs_r == k / 2 && (Py_ABS(x) & 1))) {
+ if (t >= 0) {
+ x++;
+ }
+ else {
+ x--;
+ }
+ }
+ return x;
+ }
+ else if (round == _PyTime_ROUND_CEILING) {
+ if (t >= 0) {
+ return (t + k - 1) / k;
+ }
+ else {
+ return t / k;
+ }
+ }
+ else if (round == _PyTime_ROUND_FLOOR){
+ if (t >= 0) {
+ return t / k;
+ }
+ else {
+ return (t - (k - 1)) / k;
+ }
+ }
+ else {
+ assert(round == _PyTime_ROUND_UP);
+ if (t >= 0) {
+ return (t + k - 1) / k;
+ }
+ else {
+ return (t - (k - 1)) / k;
+ }
+ }
+}
+
+_PyTime_t
+_PyTime_AsMilliseconds(_PyTime_t t, _PyTime_round_t round)
+{
+ return _PyTime_Divide(t, NS_TO_MS, round);
+}
+
+_PyTime_t
+_PyTime_AsMicroseconds(_PyTime_t t, _PyTime_round_t round)
+{
+ return _PyTime_Divide(t, NS_TO_US, round);
+}
+
+static int
+_PyTime_AsTimeval_impl(_PyTime_t t, _PyTime_t *p_secs, int *p_us,
+ _PyTime_round_t round)
+{
+ _PyTime_t secs, ns;
+ int usec;
+ int res = 0;
+
+ secs = t / SEC_TO_NS;
+ ns = t % SEC_TO_NS;
+
+ usec = (int)_PyTime_Divide(ns, US_TO_NS, round);
+ if (usec < 0) {
+ usec += SEC_TO_US;
+ if (secs != _PyTime_MIN) {
+ secs -= 1;
+ }
+ else {
+ res = -1;
+ }
+ }
+ else if (usec >= SEC_TO_US) {
+ usec -= SEC_TO_US;
+ if (secs != _PyTime_MAX) {
+ secs += 1;
+ }
+ else {
+ res = -1;
+ }
+ }
+ assert(0 <= usec && usec < SEC_TO_US);
+
+ *p_secs = secs;
+ *p_us = usec;
+
+ return res;
+}
+
+static int
+_PyTime_AsTimevalStruct_impl(_PyTime_t t, struct timeval *tv,
+ _PyTime_round_t round, int raise)
+{
+ _PyTime_t secs, secs2;
+ int us;
+ int res;
+
+ res = _PyTime_AsTimeval_impl(t, &secs, &us, round);
+
+#ifdef MS_WINDOWS
+ tv->tv_sec = (long)secs;
+#else
+ tv->tv_sec = secs;
+#endif
+ tv->tv_usec = us;
+
+ secs2 = (_PyTime_t)tv->tv_sec;
+ if (res < 0 || secs2 != secs) {
+ if (raise) {
+ error_time_t_overflow();
+ }
+ return -1;
+ }
+ return 0;
+}
+
+int
+_PyTime_AsTimeval(_PyTime_t t, struct timeval *tv, _PyTime_round_t round)
+{
+ return _PyTime_AsTimevalStruct_impl(t, tv, round, 1);
+}
+
+int
+_PyTime_AsTimeval_noraise(_PyTime_t t, struct timeval *tv, _PyTime_round_t round)
+{
+ return _PyTime_AsTimevalStruct_impl(t, tv, round, 0);
+}
+
+int
+_PyTime_AsTimevalTime_t(_PyTime_t t, time_t *p_secs, int *us,
+ _PyTime_round_t round)
+{
+ _PyTime_t secs;
+ int res;
+
+ res = _PyTime_AsTimeval_impl(t, &secs, us, round);
+
+ *p_secs = secs;
+
+ if (res < 0 || (_PyTime_t)*p_secs != secs) {
+ error_time_t_overflow();
+ return -1;
+ }
+ return 0;
+}
+
+
+#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE)
+int
+_PyTime_AsTimespec(_PyTime_t t, struct timespec *ts)
+{
+ _PyTime_t secs, nsec;
+
+ secs = t / SEC_TO_NS;
+ nsec = t % SEC_TO_NS;
+ if (nsec < 0) {
+ nsec += SEC_TO_NS;
+ secs -= 1;
+ }
+ ts->tv_sec = (time_t)secs;
+ assert(0 <= nsec && nsec < SEC_TO_NS);
+ ts->tv_nsec = nsec;
+
+ if ((_PyTime_t)ts->tv_sec != secs) {
+ error_time_t_overflow();
+ return -1;
+ }
+ return 0;
+}
+#endif
+
+static int
+pygettimeofday(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
+{
+#ifdef MS_WINDOWS
+ FILETIME system_time;
+ ULARGE_INTEGER large;
+
+ assert(info == NULL || raise);
+
+ GetSystemTimeAsFileTime(&system_time);
+ large.u.LowPart = system_time.dwLowDateTime;
+ large.u.HighPart = system_time.dwHighDateTime;
+ /* 11,644,473,600,000,000,000: number of nanoseconds between
+ the 1st january 1601 and the 1st january 1970 (369 years + 89 leap
+ days). */
+ *tp = large.QuadPart * 100 - 11644473600000000000;
+ if (info) {
+ DWORD timeAdjustment, timeIncrement;
+ BOOL isTimeAdjustmentDisabled, ok;
+
+ info->implementation = "GetSystemTimeAsFileTime()";
+ info->monotonic = 0;
+ ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
+ &isTimeAdjustmentDisabled);
+ if (!ok) {
+ PyErr_SetFromWindowsErr(0);
+ return -1;
+ }
+ info->resolution = timeIncrement * 1e-7;
+ info->adjustable = 1;
+ }
+
+#else /* MS_WINDOWS */
+ int err;
+#if defined(HAVE_CLOCK_GETTIME)
+ struct timespec ts;
+#endif
+
+#if !defined(HAVE_CLOCK_GETTIME) || defined(__APPLE__)
+ struct timeval tv;
+#endif
+
+ assert(info == NULL || raise);
+
+#ifdef HAVE_CLOCK_GETTIME
+
+#ifdef HAVE_CLOCK_GETTIME_RUNTIME
+ if (HAVE_CLOCK_GETTIME_RUNTIME) {
+#endif
+
+ err = clock_gettime(CLOCK_REALTIME, &ts);
+ if (err) {
+ if (raise) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ }
+ return -1;
+ }
+ if (pytime_fromtimespec(tp, &ts, raise) < 0) {
+ return -1;
+ }
+
+ if (info) {
+ struct timespec res;
+ info->implementation = "clock_gettime(CLOCK_REALTIME)";
+ info->monotonic = 0;
+ info->adjustable = 1;
+ if (clock_getres(CLOCK_REALTIME, &res) == 0) {
+ info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
+ }
+ else {
+ info->resolution = 1e-9;
+ }
+ }
+
+#ifdef HAVE_CLOCK_GETTIME_RUNTIME
+ } else {
+#endif
+
+#endif
+
+#if !defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_GETTIME_RUNTIME)
+
+ /* test gettimeofday() */
+ err = gettimeofday(&tv, (struct timezone *)NULL);
+ if (err) {
+ if (raise) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ }
+ return -1;
+ }
+ if (pytime_fromtimeval(tp, &tv, raise) < 0) {
+ return -1;
+ }
+
+ if (info) {
+ info->implementation = "gettimeofday()";
+ info->resolution = 1e-6;
+ info->monotonic = 0;
+ info->adjustable = 1;
+ }
+
+#if defined(HAVE_CLOCK_GETTIME_RUNTIME) && defined(HAVE_CLOCK_GETTIME)
+ } /* end of availibity block */
+#endif
+
+#endif /* !HAVE_CLOCK_GETTIME */
+#endif /* !MS_WINDOWS */
+ return 0;
+}
+
+_PyTime_t
+_PyTime_GetSystemClock(void)
+{
+ _PyTime_t t;
+ if (pygettimeofday(&t, NULL, 0) < 0) {
+ /* should not happen, _PyTime_Init() checked the clock at startup */
+ Py_FatalError("pygettimeofday() failed");
+ }
+ return t;
+}
+
+int
+_PyTime_GetSystemClockWithInfo(_PyTime_t *t, _Py_clock_info_t *info)
+{
+ return pygettimeofday(t, info, 1);
+}
+
+static int
+pymonotonic(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
+{
+#if defined(MS_WINDOWS)
+ ULONGLONG ticks;
+ _PyTime_t t;
+
+ assert(info == NULL || raise);
+
+ ticks = GetTickCount64();
+ Py_BUILD_ASSERT(sizeof(ticks) <= sizeof(_PyTime_t));
+ t = (_PyTime_t)ticks;
+
+ if (_PyTime_check_mul_overflow(t, MS_TO_NS)) {
+ if (raise) {
+ _PyTime_overflow();
+ return -1;
+ }
+ /* Hello, time traveler! */
+ Py_FatalError("pymonotonic: integer overflow");
+ }
+ *tp = t * MS_TO_NS;
+
+ if (info) {
+ DWORD timeAdjustment, timeIncrement;
+ BOOL isTimeAdjustmentDisabled, ok;
+ info->implementation = "GetTickCount64()";
+ info->monotonic = 1;
+ ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
+ &isTimeAdjustmentDisabled);
+ if (!ok) {
+ PyErr_SetFromWindowsErr(0);
+ return -1;
+ }
+ info->resolution = timeIncrement * 1e-7;
+ info->adjustable = 0;
+ }
+
+#elif defined(__APPLE__)
+ static mach_timebase_info_data_t timebase;
+ static uint64_t t0 = 0;
+ uint64_t ticks;
+
+ if (timebase.denom == 0) {
+ /* According to the Technical Q&A QA1398, mach_timebase_info() cannot
+ fail: https://developer.apple.com/library/mac/#qa/qa1398/ */
+ (void)mach_timebase_info(&timebase);
+
+ /* Sanity check: should never occur in practice */
+ if (timebase.numer < 1 || timebase.denom < 1) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "invalid mach_timebase_info");
+ return -1;
+ }
+
+ /* Check that timebase.numer and timebase.denom can be casted to
+ _PyTime_t. In practice, timebase uses uint32_t, so casting cannot
+ overflow. At the end, only make sure that the type is uint32_t
+ (_PyTime_t is 64-bit long). */
+ assert(sizeof(timebase.numer) < sizeof(_PyTime_t));
+ assert(sizeof(timebase.denom) < sizeof(_PyTime_t));
+
+ /* Make sure that (ticks * timebase.numer) cannot overflow in
+ _PyTime_MulDiv(), with ticks < timebase.denom.
+
+ Known time bases:
+
+ * always (1, 1) on Intel
+ * (1000000000, 33333335) or (1000000000, 25000000) on PowerPC
+
+ None of these time bases can overflow with 64-bit _PyTime_t, but
+ check for overflow, just in case. */
+ if ((_PyTime_t)timebase.numer > _PyTime_MAX / (_PyTime_t)timebase.denom) {
+ PyErr_SetString(PyExc_OverflowError,
+ "mach_timebase_info is too large");
+ return -1;
+ }
+
+ t0 = mach_absolute_time();
+ }
+
+ if (info) {
+ info->implementation = "mach_absolute_time()";
+ info->resolution = (double)timebase.numer / (double)timebase.denom * 1e-9;
+ info->monotonic = 1;
+ info->adjustable = 0;
+ }
+
+ ticks = mach_absolute_time();
+ /* Use a "time zero" to reduce precision loss when converting time
+ to floatting point number, as in time.monotonic(). */
+ ticks -= t0;
+ *tp = _PyTime_MulDiv(ticks,
+ (_PyTime_t)timebase.numer,
+ (_PyTime_t)timebase.denom);
+
+#elif defined(__hpux)
+ hrtime_t time;
+
+ time = gethrtime();
+ if (time == -1) {
+ if (raise) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ }
+ return -1;
+ }
+
+ *tp = time;
+
+ if (info) {
+ info->implementation = "gethrtime()";
+ info->resolution = 1e-9;
+ info->monotonic = 1;
+ info->adjustable = 0;
+ }
+
+#else
+ struct timespec ts;
+#ifdef CLOCK_HIGHRES
+ const clockid_t clk_id = CLOCK_HIGHRES;
+ const char *implementation = "clock_gettime(CLOCK_HIGHRES)";
+#else
+ const clockid_t clk_id = CLOCK_MONOTONIC;
+ const char *implementation = "clock_gettime(CLOCK_MONOTONIC)";
+#endif
+
+ assert(info == NULL || raise);
+
+ if (clock_gettime(clk_id, &ts) != 0) {
+ if (raise) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+ return -1;
+ }
+
+ if (info) {
+ struct timespec res;
+ info->monotonic = 1;
+ info->implementation = implementation;
+ info->adjustable = 0;
+ if (clock_getres(clk_id, &res) != 0) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+ info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
+ }
+ if (pytime_fromtimespec(tp, &ts, raise) < 0) {
+ return -1;
+ }
+#endif
+ return 0;
+}
+
+_PyTime_t
+_PyTime_GetMonotonicClock(void)
+{
+ _PyTime_t t;
+ if (pymonotonic(&t, NULL, 0) < 0) {
+ /* should not happen, _PyTime_Init() checked that monotonic clock at
+ startup */
+ Py_FatalError("pymonotonic() failed");
+ }
+ return t;
+}
+
+int
+_PyTime_GetMonotonicClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
+{
+ return pymonotonic(tp, info, 1);
+}
+
+
+#ifdef MS_WINDOWS
+static int
+win_perf_counter(_PyTime_t *tp, _Py_clock_info_t *info)
+{
+ static LONGLONG frequency = 0;
+ static LONGLONG t0 = 0;
+ LARGE_INTEGER now;
+ LONGLONG ticksll;
+ _PyTime_t ticks;
+
+ if (frequency == 0) {
+ LARGE_INTEGER freq;
+ if (!QueryPerformanceFrequency(&freq)) {
+ PyErr_SetFromWindowsErr(0);
+ return -1;
+ }
+ frequency = freq.QuadPart;
+
+ /* Sanity check: should never occur in practice */
+ if (frequency < 1) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "invalid QueryPerformanceFrequency");
+ return -1;
+ }
+
+ /* Check that frequency can be casted to _PyTime_t.
+
+ Make also sure that (ticks * SEC_TO_NS) cannot overflow in
+ _PyTime_MulDiv(), with ticks < frequency.
+
+ Known QueryPerformanceFrequency() values:
+
+ * 10,000,000 (10 MHz): 100 ns resolution
+ * 3,579,545 Hz (3.6 MHz): 279 ns resolution
+
+ None of these frequencies can overflow with 64-bit _PyTime_t, but
+ check for overflow, just in case. */
+ if (frequency > _PyTime_MAX
+ || frequency > (LONGLONG)_PyTime_MAX / (LONGLONG)SEC_TO_NS) {
+ PyErr_SetString(PyExc_OverflowError,
+ "QueryPerformanceFrequency is too large");
+ return -1;
+ }
+
+ QueryPerformanceCounter(&now);
+ t0 = now.QuadPart;
+ }
+
+ if (info) {
+ info->implementation = "QueryPerformanceCounter()";
+ info->resolution = 1.0 / (double)frequency;
+ info->monotonic = 1;
+ info->adjustable = 0;
+ }
+
+ QueryPerformanceCounter(&now);
+ ticksll = now.QuadPart;
+
+ /* Use a "time zero" to reduce precision loss when converting time
+ to floatting point number, as in time.perf_counter(). */
+ ticksll -= t0;
+
+ /* Make sure that casting LONGLONG to _PyTime_t cannot overflow,
+ both types are signed */
+ Py_BUILD_ASSERT(sizeof(ticksll) <= sizeof(ticks));
+ ticks = (_PyTime_t)ticksll;
+
+ *tp = _PyTime_MulDiv(ticks, SEC_TO_NS, (_PyTime_t)frequency);
+ return 0;
+}
+#endif
+
+
+int
+_PyTime_GetPerfCounterWithInfo(_PyTime_t *t, _Py_clock_info_t *info)
+{
+#ifdef MS_WINDOWS
+ return win_perf_counter(t, info);
+#else
+ return _PyTime_GetMonotonicClockWithInfo(t, info);
+#endif
+}
+
+
+_PyTime_t
+_PyTime_GetPerfCounter(void)
+{
+ _PyTime_t t;
+ if (_PyTime_GetPerfCounterWithInfo(&t, NULL)) {
+ Py_FatalError("_PyTime_GetPerfCounterWithInfo() failed");
+ }
+ return t;
+}
+
+
+int
+_PyTime_Init(void)
+{
+ /* check that time.time(), time.monotonic() and time.perf_counter() clocks
+ are working properly to not have to check for exceptions at runtime. If
+ a clock works once, it cannot fail in next calls. */
+ _PyTime_t t;
+ if (_PyTime_GetSystemClockWithInfo(&t, NULL) < 0) {
+ return -1;
+ }
+ if (_PyTime_GetMonotonicClockWithInfo(&t, NULL) < 0) {
+ return -1;
+ }
+ if (_PyTime_GetPerfCounterWithInfo(&t, NULL) < 0) {
+ return -1;
+ }
+ return 0;
+}
+
+int
+_PyTime_localtime(time_t t, struct tm *tm)
+{
+#ifdef MS_WINDOWS
+ int error;
+
+ error = localtime_s(tm, &t);
+ if (error != 0) {
+ errno = error;
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+ return 0;
+#else /* !MS_WINDOWS */
+
+#if defined(_AIX) && (SIZEOF_TIME_T < 8)
+ /* bpo-34373: AIX does not return NULL if t is too small or too large */
+ if (t < -2145916800 /* 1902-01-01 */
+ || t > 2145916800 /* 2038-01-01 */) {
+ errno = EINVAL;
+ PyErr_SetString(PyExc_OverflowError,
+ "localtime argument out of range");
+ return -1;
+ }
+#endif
+
+ errno = 0;
+ if (localtime_r(&t, tm) == NULL) {
+ if (errno == 0) {
+ errno = EINVAL;
+ }
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+ return 0;
+#endif /* MS_WINDOWS */
+}
+
+int
+_PyTime_gmtime(time_t t, struct tm *tm)
+{
+#ifdef MS_WINDOWS
+ int error;
+
+ error = gmtime_s(tm, &t);
+ if (error != 0) {
+ errno = error;
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+ return 0;
+#else /* !MS_WINDOWS */
+ if (gmtime_r(&t, tm) == NULL) {
+#ifdef EINVAL
+ if (errno == 0) {
+ errno = EINVAL;
+ }
+#endif
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+ return 0;
+#endif /* MS_WINDOWS */
+}
diff --git a/contrib/tools/python3/src/Python/structmember.c b/contrib/tools/python3/src/Python/structmember.c
new file mode 100644
index 00000000000..ba88e15f938
--- /dev/null
+++ b/contrib/tools/python3/src/Python/structmember.c
@@ -0,0 +1,291 @@
+
+/* Map C struct members to Python object attributes */
+
+#include "Python.h"
+#include "structmember.h" // PyMemberDef
+
+PyObject *
+PyMember_GetOne(const char *addr, PyMemberDef *l)
+{
+ PyObject *v;
+
+ addr += l->offset;
+ switch (l->type) {
+ case T_BOOL:
+ v = PyBool_FromLong(*(char*)addr);
+ break;
+ case T_BYTE:
+ v = PyLong_FromLong(*(char*)addr);
+ break;
+ case T_UBYTE:
+ v = PyLong_FromUnsignedLong(*(unsigned char*)addr);
+ break;
+ case T_SHORT:
+ v = PyLong_FromLong(*(short*)addr);
+ break;
+ case T_USHORT:
+ v = PyLong_FromUnsignedLong(*(unsigned short*)addr);
+ break;
+ case T_INT:
+ v = PyLong_FromLong(*(int*)addr);
+ break;
+ case T_UINT:
+ v = PyLong_FromUnsignedLong(*(unsigned int*)addr);
+ break;
+ case T_LONG:
+ v = PyLong_FromLong(*(long*)addr);
+ break;
+ case T_ULONG:
+ v = PyLong_FromUnsignedLong(*(unsigned long*)addr);
+ break;
+ case T_PYSSIZET:
+ v = PyLong_FromSsize_t(*(Py_ssize_t*)addr);
+ break;
+ case T_FLOAT:
+ v = PyFloat_FromDouble((double)*(float*)addr);
+ break;
+ case T_DOUBLE:
+ v = PyFloat_FromDouble(*(double*)addr);
+ break;
+ case T_STRING:
+ if (*(char**)addr == NULL) {
+ Py_INCREF(Py_None);
+ v = Py_None;
+ }
+ else
+ v = PyUnicode_FromString(*(char**)addr);
+ break;
+ case T_STRING_INPLACE:
+ v = PyUnicode_FromString((char*)addr);
+ break;
+ case T_CHAR:
+ v = PyUnicode_FromStringAndSize((char*)addr, 1);
+ break;
+ case T_OBJECT:
+ v = *(PyObject **)addr;
+ if (v == NULL)
+ v = Py_None;
+ Py_INCREF(v);
+ break;
+ case T_OBJECT_EX:
+ v = *(PyObject **)addr;
+ if (v == NULL)
+ PyErr_SetString(PyExc_AttributeError, l->name);
+ Py_XINCREF(v);
+ break;
+ case T_LONGLONG:
+ v = PyLong_FromLongLong(*(long long *)addr);
+ break;
+ case T_ULONGLONG:
+ v = PyLong_FromUnsignedLongLong(*(unsigned long long *)addr);
+ break;
+ case T_NONE:
+ v = Py_None;
+ Py_INCREF(v);
+ break;
+ default:
+ PyErr_SetString(PyExc_SystemError, "bad memberdescr type");
+ v = NULL;
+ }
+ return v;
+}
+
+#define WARN(msg) \
+ do { \
+ if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 1) < 0) \
+ return -1; \
+ } while (0)
+
+int
+PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
+{
+ PyObject *oldv;
+
+ addr += l->offset;
+
+ if ((l->flags & READONLY))
+ {
+ PyErr_SetString(PyExc_AttributeError, "readonly attribute");
+ return -1;
+ }
+ if (v == NULL) {
+ if (l->type == T_OBJECT_EX) {
+ /* Check if the attribute is set. */
+ if (*(PyObject **)addr == NULL) {
+ PyErr_SetString(PyExc_AttributeError, l->name);
+ return -1;
+ }
+ }
+ else if (l->type != T_OBJECT) {
+ PyErr_SetString(PyExc_TypeError,
+ "can't delete numeric/char attribute");
+ return -1;
+ }
+ }
+ switch (l->type) {
+ case T_BOOL:{
+ if (!PyBool_Check(v)) {
+ PyErr_SetString(PyExc_TypeError,
+ "attribute value type must be bool");
+ return -1;
+ }
+ if (v == Py_True)
+ *(char*)addr = (char) 1;
+ else
+ *(char*)addr = (char) 0;
+ break;
+ }
+ case T_BYTE:{
+ long long_val = PyLong_AsLong(v);
+ if ((long_val == -1) && PyErr_Occurred())
+ return -1;
+ *(char*)addr = (char)long_val;
+ /* XXX: For compatibility, only warn about truncations
+ for now. */
+ if ((long_val > CHAR_MAX) || (long_val < CHAR_MIN))
+ WARN("Truncation of value to char");
+ break;
+ }
+ case T_UBYTE:{
+ long long_val = PyLong_AsLong(v);
+ if ((long_val == -1) && PyErr_Occurred())
+ return -1;
+ *(unsigned char*)addr = (unsigned char)long_val;
+ if ((long_val > UCHAR_MAX) || (long_val < 0))
+ WARN("Truncation of value to unsigned char");
+ break;
+ }
+ case T_SHORT:{
+ long long_val = PyLong_AsLong(v);
+ if ((long_val == -1) && PyErr_Occurred())
+ return -1;
+ *(short*)addr = (short)long_val;
+ if ((long_val > SHRT_MAX) || (long_val < SHRT_MIN))
+ WARN("Truncation of value to short");
+ break;
+ }
+ case T_USHORT:{
+ long long_val = PyLong_AsLong(v);
+ if ((long_val == -1) && PyErr_Occurred())
+ return -1;
+ *(unsigned short*)addr = (unsigned short)long_val;
+ if ((long_val > USHRT_MAX) || (long_val < 0))
+ WARN("Truncation of value to unsigned short");
+ break;
+ }
+ case T_INT:{
+ long long_val = PyLong_AsLong(v);
+ if ((long_val == -1) && PyErr_Occurred())
+ return -1;
+ *(int *)addr = (int)long_val;
+ if ((long_val > INT_MAX) || (long_val < INT_MIN))
+ WARN("Truncation of value to int");
+ break;
+ }
+ case T_UINT:{
+ unsigned long ulong_val = PyLong_AsUnsignedLong(v);
+ if ((ulong_val == (unsigned long)-1) && PyErr_Occurred()) {
+ /* XXX: For compatibility, accept negative int values
+ as well. */
+ PyErr_Clear();
+ ulong_val = PyLong_AsLong(v);
+ if ((ulong_val == (unsigned long)-1) &&
+ PyErr_Occurred())
+ return -1;
+ *(unsigned int *)addr = (unsigned int)ulong_val;
+ WARN("Writing negative value into unsigned field");
+ } else
+ *(unsigned int *)addr = (unsigned int)ulong_val;
+ if (ulong_val > UINT_MAX)
+ WARN("Truncation of value to unsigned int");
+ break;
+ }
+ case T_LONG:{
+ *(long*)addr = PyLong_AsLong(v);
+ if ((*(long*)addr == -1) && PyErr_Occurred())
+ return -1;
+ break;
+ }
+ case T_ULONG:{
+ *(unsigned long*)addr = PyLong_AsUnsignedLong(v);
+ if ((*(unsigned long*)addr == (unsigned long)-1)
+ && PyErr_Occurred()) {
+ /* XXX: For compatibility, accept negative int values
+ as well. */
+ PyErr_Clear();
+ *(unsigned long*)addr = PyLong_AsLong(v);
+ if ((*(unsigned long*)addr == (unsigned long)-1)
+ && PyErr_Occurred())
+ return -1;
+ WARN("Writing negative value into unsigned field");
+ }
+ break;
+ }
+ case T_PYSSIZET:{
+ *(Py_ssize_t*)addr = PyLong_AsSsize_t(v);
+ if ((*(Py_ssize_t*)addr == (Py_ssize_t)-1)
+ && PyErr_Occurred())
+ return -1;
+ break;
+ }
+ case T_FLOAT:{
+ double double_val = PyFloat_AsDouble(v);
+ if ((double_val == -1) && PyErr_Occurred())
+ return -1;
+ *(float*)addr = (float)double_val;
+ break;
+ }
+ case T_DOUBLE:
+ *(double*)addr = PyFloat_AsDouble(v);
+ if ((*(double*)addr == -1) && PyErr_Occurred())
+ return -1;
+ break;
+ case T_OBJECT:
+ case T_OBJECT_EX:
+ Py_XINCREF(v);
+ oldv = *(PyObject **)addr;
+ *(PyObject **)addr = v;
+ Py_XDECREF(oldv);
+ break;
+ case T_CHAR: {
+ const char *string;
+ Py_ssize_t len;
+
+ string = PyUnicode_AsUTF8AndSize(v, &len);
+ if (string == NULL || len != 1) {
+ PyErr_BadArgument();
+ return -1;
+ }
+ *(char*)addr = string[0];
+ break;
+ }
+ case T_STRING:
+ case T_STRING_INPLACE:
+ PyErr_SetString(PyExc_TypeError, "readonly attribute");
+ return -1;
+ case T_LONGLONG:{
+ long long value;
+ *(long long*)addr = value = PyLong_AsLongLong(v);
+ if ((value == -1) && PyErr_Occurred())
+ return -1;
+ break;
+ }
+ case T_ULONGLONG:{
+ unsigned long long value;
+ /* ??? PyLong_AsLongLong accepts an int, but PyLong_AsUnsignedLongLong
+ doesn't ??? */
+ if (PyLong_Check(v))
+ *(unsigned long long*)addr = value = PyLong_AsUnsignedLongLong(v);
+ else
+ *(unsigned long long*)addr = value = PyLong_AsLong(v);
+ if ((value == (unsigned long long)-1) && PyErr_Occurred())
+ return -1;
+ break;
+ }
+ default:
+ PyErr_Format(PyExc_SystemError,
+ "bad memberdescr type for %s", l->name);
+ return -1;
+ }
+ return 0;
+}
diff --git a/contrib/tools/python3/src/Python/symtable.c b/contrib/tools/python3/src/Python/symtable.c
new file mode 100644
index 00000000000..d192f31deef
--- /dev/null
+++ b/contrib/tools/python3/src/Python/symtable.c
@@ -0,0 +1,1936 @@
+#include "Python.h"
+#include "pycore_pystate.h" // _PyThreadState_GET()
+#include "symtable.h"
+#undef Yield /* undefine macro conflicting with <winbase.h> */
+#include "structmember.h" // PyMemberDef
+
+/* error strings used for warnings */
+#define GLOBAL_PARAM \
+"name '%U' is parameter and global"
+
+#define NONLOCAL_PARAM \
+"name '%U' is parameter and nonlocal"
+
+#define GLOBAL_AFTER_ASSIGN \
+"name '%U' is assigned to before global declaration"
+
+#define NONLOCAL_AFTER_ASSIGN \
+"name '%U' is assigned to before nonlocal declaration"
+
+#define GLOBAL_AFTER_USE \
+"name '%U' is used prior to global declaration"
+
+#define NONLOCAL_AFTER_USE \
+"name '%U' is used prior to nonlocal declaration"
+
+#define GLOBAL_ANNOT \
+"annotated name '%U' can't be global"
+
+#define NONLOCAL_ANNOT \
+"annotated name '%U' can't be nonlocal"
+
+#define IMPORT_STAR_WARNING "import * only allowed at module level"
+
+#define NAMED_EXPR_COMP_IN_CLASS \
+"assignment expression within a comprehension cannot be used in a class body"
+
+#define NAMED_EXPR_COMP_CONFLICT \
+"assignment expression cannot rebind comprehension iteration variable '%U'"
+
+#define NAMED_EXPR_COMP_INNER_LOOP_CONFLICT \
+"comprehension inner loop cannot rebind assignment expression target '%U'"
+
+#define NAMED_EXPR_COMP_ITER_EXPR \
+"assignment expression cannot be used in a comprehension iterable expression"
+
+static PySTEntryObject *
+ste_new(struct symtable *st, identifier name, _Py_block_ty block,
+ void *key, int lineno, int col_offset)
+{
+ PySTEntryObject *ste = NULL;
+ PyObject *k = NULL;
+
+ k = PyLong_FromVoidPtr(key);
+ if (k == NULL)
+ goto fail;
+ ste = PyObject_New(PySTEntryObject, &PySTEntry_Type);
+ if (ste == NULL) {
+ Py_DECREF(k);
+ goto fail;
+ }
+ ste->ste_table = st;
+ ste->ste_id = k; /* ste owns reference to k */
+
+ Py_INCREF(name);
+ ste->ste_name = name;
+
+ ste->ste_symbols = NULL;
+ ste->ste_varnames = NULL;
+ ste->ste_children = NULL;
+
+ ste->ste_directives = NULL;
+
+ ste->ste_type = block;
+ ste->ste_nested = 0;
+ ste->ste_free = 0;
+ ste->ste_varargs = 0;
+ ste->ste_varkeywords = 0;
+ ste->ste_opt_lineno = 0;
+ ste->ste_opt_col_offset = 0;
+ ste->ste_lineno = lineno;
+ ste->ste_col_offset = col_offset;
+
+ if (st->st_cur != NULL &&
+ (st->st_cur->ste_nested ||
+ st->st_cur->ste_type == FunctionBlock))
+ ste->ste_nested = 1;
+ ste->ste_child_free = 0;
+ ste->ste_generator = 0;
+ ste->ste_coroutine = 0;
+ ste->ste_comprehension = 0;
+ ste->ste_returns_value = 0;
+ ste->ste_needs_class_closure = 0;
+ ste->ste_comp_iter_target = 0;
+ ste->ste_comp_iter_expr = 0;
+
+ ste->ste_symbols = PyDict_New();
+ ste->ste_varnames = PyList_New(0);
+ ste->ste_children = PyList_New(0);
+ if (ste->ste_symbols == NULL
+ || ste->ste_varnames == NULL
+ || ste->ste_children == NULL)
+ goto fail;
+
+ if (PyDict_SetItem(st->st_blocks, ste->ste_id, (PyObject *)ste) < 0)
+ goto fail;
+
+ return ste;
+ fail:
+ Py_XDECREF(ste);
+ return NULL;
+}
+
+static PyObject *
+ste_repr(PySTEntryObject *ste)
+{
+ return PyUnicode_FromFormat("<symtable entry %U(%ld), line %d>",
+ ste->ste_name,
+ PyLong_AS_LONG(ste->ste_id), ste->ste_lineno);
+}
+
+static void
+ste_dealloc(PySTEntryObject *ste)
+{
+ ste->ste_table = NULL;
+ Py_XDECREF(ste->ste_id);
+ Py_XDECREF(ste->ste_name);
+ Py_XDECREF(ste->ste_symbols);
+ Py_XDECREF(ste->ste_varnames);
+ Py_XDECREF(ste->ste_children);
+ Py_XDECREF(ste->ste_directives);
+ PyObject_Del(ste);
+}
+
+#define OFF(x) offsetof(PySTEntryObject, x)
+
+static PyMemberDef ste_memberlist[] = {
+ {"id", T_OBJECT, OFF(ste_id), READONLY},
+ {"name", T_OBJECT, OFF(ste_name), READONLY},
+ {"symbols", T_OBJECT, OFF(ste_symbols), READONLY},
+ {"varnames", T_OBJECT, OFF(ste_varnames), READONLY},
+ {"children", T_OBJECT, OFF(ste_children), READONLY},
+ {"nested", T_INT, OFF(ste_nested), READONLY},
+ {"type", T_INT, OFF(ste_type), READONLY},
+ {"lineno", T_INT, OFF(ste_lineno), READONLY},
+ {NULL}
+};
+
+PyTypeObject PySTEntry_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "symtable entry",
+ sizeof(PySTEntryObject),
+ 0,
+ (destructor)ste_dealloc, /* tp_dealloc */
+ 0, /* tp_vectorcall_offset */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_as_async */
+ (reprfunc)ste_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ ste_memberlist, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+};
+
+static int symtable_analyze(struct symtable *st);
+static int symtable_enter_block(struct symtable *st, identifier name,
+ _Py_block_ty block, void *ast, int lineno,
+ int col_offset);
+static int symtable_exit_block(struct symtable *st);
+static int symtable_visit_stmt(struct symtable *st, stmt_ty s);
+static int symtable_visit_expr(struct symtable *st, expr_ty s);
+static int symtable_visit_genexp(struct symtable *st, expr_ty s);
+static int symtable_visit_listcomp(struct symtable *st, expr_ty s);
+static int symtable_visit_setcomp(struct symtable *st, expr_ty s);
+static int symtable_visit_dictcomp(struct symtable *st, expr_ty s);
+static int symtable_visit_arguments(struct symtable *st, arguments_ty);
+static int symtable_visit_excepthandler(struct symtable *st, excepthandler_ty);
+static int symtable_visit_alias(struct symtable *st, alias_ty);
+static int symtable_visit_comprehension(struct symtable *st, comprehension_ty);
+static int symtable_visit_keyword(struct symtable *st, keyword_ty);
+static int symtable_visit_params(struct symtable *st, asdl_seq *args);
+static int symtable_visit_argannotations(struct symtable *st, asdl_seq *args);
+static int symtable_implicit_arg(struct symtable *st, int pos);
+static int symtable_visit_annotations(struct symtable *st, arguments_ty, expr_ty);
+static int symtable_visit_withitem(struct symtable *st, withitem_ty item);
+
+
+static identifier top = NULL, lambda = NULL, genexpr = NULL,
+ listcomp = NULL, setcomp = NULL, dictcomp = NULL,
+ __class__ = NULL;
+
+#define GET_IDENTIFIER(VAR) \
+ ((VAR) ? (VAR) : ((VAR) = PyUnicode_InternFromString(# VAR)))
+
+#define DUPLICATE_ARGUMENT \
+"duplicate argument '%U' in function definition"
+
+static struct symtable *
+symtable_new(void)
+{
+ struct symtable *st;
+
+ st = (struct symtable *)PyMem_Malloc(sizeof(struct symtable));
+ if (st == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ st->st_filename = NULL;
+ st->st_blocks = NULL;
+
+ if ((st->st_stack = PyList_New(0)) == NULL)
+ goto fail;
+ if ((st->st_blocks = PyDict_New()) == NULL)
+ goto fail;
+ st->st_cur = NULL;
+ st->st_private = NULL;
+ return st;
+ fail:
+ PySymtable_Free(st);
+ return NULL;
+}
+
+/* When compiling the use of C stack is probably going to be a lot
+ lighter than when executing Python code but still can overflow
+ and causing a Python crash if not checked (e.g. eval("()"*300000)).
+ Using the current recursion limit for the compiler seems too
+ restrictive (it caused at least one test to fail) so a factor is
+ used to allow deeper recursion when compiling an expression.
+
+ Using a scaling factor means this should automatically adjust when
+ the recursion limit is adjusted for small or large C stack allocations.
+*/
+#define COMPILER_STACK_FRAME_SCALE 3
+
+struct symtable *
+PySymtable_BuildObject(mod_ty mod, PyObject *filename, PyFutureFeatures *future)
+{
+ struct symtable *st = symtable_new();
+ asdl_seq *seq;
+ int i;
+ PyThreadState *tstate;
+ int recursion_limit = Py_GetRecursionLimit();
+ int starting_recursion_depth;
+
+ if (st == NULL)
+ return NULL;
+ if (filename == NULL) {
+ PySymtable_Free(st);
+ return NULL;
+ }
+ Py_INCREF(filename);
+ st->st_filename = filename;
+ st->st_future = future;
+
+ /* Setup recursion depth check counters */
+ tstate = _PyThreadState_GET();
+ if (!tstate) {
+ PySymtable_Free(st);
+ return NULL;
+ }
+ /* Be careful here to prevent overflow. */
+ starting_recursion_depth = (tstate->recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ?
+ tstate->recursion_depth * COMPILER_STACK_FRAME_SCALE : tstate->recursion_depth;
+ st->recursion_depth = starting_recursion_depth;
+ st->recursion_limit = (recursion_limit < INT_MAX / COMPILER_STACK_FRAME_SCALE) ?
+ recursion_limit * COMPILER_STACK_FRAME_SCALE : recursion_limit;
+
+ /* Make the initial symbol information gathering pass */
+ if (!GET_IDENTIFIER(top) ||
+ !symtable_enter_block(st, top, ModuleBlock, (void *)mod, 0, 0)) {
+ PySymtable_Free(st);
+ return NULL;
+ }
+
+ st->st_top = st->st_cur;
+ switch (mod->kind) {
+ case Module_kind:
+ seq = mod->v.Module.body;
+ for (i = 0; i < asdl_seq_LEN(seq); i++)
+ if (!symtable_visit_stmt(st,
+ (stmt_ty)asdl_seq_GET(seq, i)))
+ goto error;
+ break;
+ case Expression_kind:
+ if (!symtable_visit_expr(st, mod->v.Expression.body))
+ goto error;
+ break;
+ case Interactive_kind:
+ seq = mod->v.Interactive.body;
+ for (i = 0; i < asdl_seq_LEN(seq); i++)
+ if (!symtable_visit_stmt(st,
+ (stmt_ty)asdl_seq_GET(seq, i)))
+ goto error;
+ break;
+ case FunctionType_kind:
+ PyErr_SetString(PyExc_RuntimeError,
+ "this compiler does not handle FunctionTypes");
+ goto error;
+ }
+ if (!symtable_exit_block(st)) {
+ PySymtable_Free(st);
+ return NULL;
+ }
+ /* Check that the recursion depth counting balanced correctly */
+ if (st->recursion_depth != starting_recursion_depth) {
+ PyErr_Format(PyExc_SystemError,
+ "symtable analysis recursion depth mismatch (before=%d, after=%d)",
+ starting_recursion_depth, st->recursion_depth);
+ PySymtable_Free(st);
+ return NULL;
+ }
+ /* Make the second symbol analysis pass */
+ if (symtable_analyze(st))
+ return st;
+ PySymtable_Free(st);
+ return NULL;
+ error:
+ (void) symtable_exit_block(st);
+ PySymtable_Free(st);
+ return NULL;
+}
+
+struct symtable *
+PySymtable_Build(mod_ty mod, const char *filename_str, PyFutureFeatures *future)
+{
+ PyObject *filename;
+ struct symtable *st;
+ filename = PyUnicode_DecodeFSDefault(filename_str);
+ if (filename == NULL)
+ return NULL;
+ st = PySymtable_BuildObject(mod, filename, future);
+ Py_DECREF(filename);
+ return st;
+}
+
+void
+PySymtable_Free(struct symtable *st)
+{
+ Py_XDECREF(st->st_filename);
+ Py_XDECREF(st->st_blocks);
+ Py_XDECREF(st->st_stack);
+ PyMem_Free((void *)st);
+}
+
+PySTEntryObject *
+PySymtable_Lookup(struct symtable *st, void *key)
+{
+ PyObject *k, *v;
+
+ k = PyLong_FromVoidPtr(key);
+ if (k == NULL)
+ return NULL;
+ v = PyDict_GetItemWithError(st->st_blocks, k);
+ if (v) {
+ assert(PySTEntry_Check(v));
+ Py_INCREF(v);
+ }
+ else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_KeyError,
+ "unknown symbol table entry");
+ }
+
+ Py_DECREF(k);
+ return (PySTEntryObject *)v;
+}
+
+static long
+_PyST_GetSymbol(PySTEntryObject *ste, PyObject *name)
+{
+ PyObject *v = PyDict_GetItem(ste->ste_symbols, name);
+ if (!v)
+ return 0;
+ assert(PyLong_Check(v));
+ return PyLong_AS_LONG(v);
+}
+
+int
+PyST_GetScope(PySTEntryObject *ste, PyObject *name)
+{
+ long symbol = _PyST_GetSymbol(ste, name);
+ return (symbol >> SCOPE_OFFSET) & SCOPE_MASK;
+}
+
+static int
+error_at_directive(PySTEntryObject *ste, PyObject *name)
+{
+ Py_ssize_t i;
+ PyObject *data;
+ assert(ste->ste_directives);
+ for (i = 0; i < PyList_GET_SIZE(ste->ste_directives); i++) {
+ data = PyList_GET_ITEM(ste->ste_directives, i);
+ assert(PyTuple_CheckExact(data));
+ assert(PyUnicode_CheckExact(PyTuple_GET_ITEM(data, 0)));
+ if (PyUnicode_Compare(PyTuple_GET_ITEM(data, 0), name) == 0) {
+ PyErr_SyntaxLocationObject(ste->ste_table->st_filename,
+ PyLong_AsLong(PyTuple_GET_ITEM(data, 1)),
+ PyLong_AsLong(PyTuple_GET_ITEM(data, 2)) + 1);
+
+ return 0;
+ }
+ }
+ PyErr_SetString(PyExc_RuntimeError,
+ "BUG: internal directive bookkeeping broken");
+ return 0;
+}
+
+
+/* Analyze raw symbol information to determine scope of each name.
+
+ The next several functions are helpers for symtable_analyze(),
+ which determines whether a name is local, global, or free. In addition,
+ it determines which local variables are cell variables; they provide
+ bindings that are used for free variables in enclosed blocks.
+
+ There are also two kinds of global variables, implicit and explicit. An
+ explicit global is declared with the global statement. An implicit
+ global is a free variable for which the compiler has found no binding
+ in an enclosing function scope. The implicit global is either a global
+ or a builtin. Python's module and class blocks use the xxx_NAME opcodes
+ to handle these names to implement slightly odd semantics. In such a
+ block, the name is treated as global until it is assigned to; then it
+ is treated as a local.
+
+ The symbol table requires two passes to determine the scope of each name.
+ The first pass collects raw facts from the AST via the symtable_visit_*
+ functions: the name is a parameter here, the name is used but not defined
+ here, etc. The second pass analyzes these facts during a pass over the
+ PySTEntryObjects created during pass 1.
+
+ When a function is entered during the second pass, the parent passes
+ the set of all name bindings visible to its children. These bindings
+ are used to determine if non-local variables are free or implicit globals.
+ Names which are explicitly declared nonlocal must exist in this set of
+ visible names - if they do not, a syntax error is raised. After doing
+ the local analysis, it analyzes each of its child blocks using an
+ updated set of name bindings.
+
+ The children update the free variable set. If a local variable is added to
+ the free variable set by the child, the variable is marked as a cell. The
+ function object being defined must provide runtime storage for the variable
+ that may outlive the function's frame. Cell variables are removed from the
+ free set before the analyze function returns to its parent.
+
+ During analysis, the names are:
+ symbols: dict mapping from symbol names to flag values (including offset scope values)
+ scopes: dict mapping from symbol names to scope values (no offset)
+ local: set of all symbol names local to the current scope
+ bound: set of all symbol names local to a containing function scope
+ free: set of all symbol names referenced but not bound in child scopes
+ global: set of all symbol names explicitly declared as global
+*/
+
+#define SET_SCOPE(DICT, NAME, I) { \
+ PyObject *o = PyLong_FromLong(I); \
+ if (!o) \
+ return 0; \
+ if (PyDict_SetItem((DICT), (NAME), o) < 0) { \
+ Py_DECREF(o); \
+ return 0; \
+ } \
+ Py_DECREF(o); \
+}
+
+/* Decide on scope of name, given flags.
+
+ The namespace dictionaries may be modified to record information
+ about the new name. For example, a new global will add an entry to
+ global. A name that was global can be changed to local.
+*/
+
+static int
+analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags,
+ PyObject *bound, PyObject *local, PyObject *free,
+ PyObject *global)
+{
+ if (flags & DEF_GLOBAL) {
+ if (flags & DEF_NONLOCAL) {
+ PyErr_Format(PyExc_SyntaxError,
+ "name '%U' is nonlocal and global",
+ name);
+ return error_at_directive(ste, name);
+ }
+ SET_SCOPE(scopes, name, GLOBAL_EXPLICIT);
+ if (PySet_Add(global, name) < 0)
+ return 0;
+ if (bound && (PySet_Discard(bound, name) < 0))
+ return 0;
+ return 1;
+ }
+ if (flags & DEF_NONLOCAL) {
+ if (!bound) {
+ PyErr_Format(PyExc_SyntaxError,
+ "nonlocal declaration not allowed at module level");
+ return error_at_directive(ste, name);
+ }
+ if (!PySet_Contains(bound, name)) {
+ PyErr_Format(PyExc_SyntaxError,
+ "no binding for nonlocal '%U' found",
+ name);
+
+ return error_at_directive(ste, name);
+ }
+ SET_SCOPE(scopes, name, FREE);
+ ste->ste_free = 1;
+ return PySet_Add(free, name) >= 0;
+ }
+ if (flags & DEF_BOUND) {
+ SET_SCOPE(scopes, name, LOCAL);
+ if (PySet_Add(local, name) < 0)
+ return 0;
+ if (PySet_Discard(global, name) < 0)
+ return 0;
+ return 1;
+ }
+ /* If an enclosing block has a binding for this name, it
+ is a free variable rather than a global variable.
+ Note that having a non-NULL bound implies that the block
+ is nested.
+ */
+ if (bound && PySet_Contains(bound, name)) {
+ SET_SCOPE(scopes, name, FREE);
+ ste->ste_free = 1;
+ return PySet_Add(free, name) >= 0;
+ }
+ /* If a parent has a global statement, then call it global
+ explicit? It could also be global implicit.
+ */
+ if (global && PySet_Contains(global, name)) {
+ SET_SCOPE(scopes, name, GLOBAL_IMPLICIT);
+ return 1;
+ }
+ if (ste->ste_nested)
+ ste->ste_free = 1;
+ SET_SCOPE(scopes, name, GLOBAL_IMPLICIT);
+ return 1;
+}
+
+#undef SET_SCOPE
+
+/* If a name is defined in free and also in locals, then this block
+ provides the binding for the free variable. The name should be
+ marked CELL in this block and removed from the free list.
+
+ Note that the current block's free variables are included in free.
+ That's safe because no name can be free and local in the same scope.
+*/
+
+static int
+analyze_cells(PyObject *scopes, PyObject *free)
+{
+ PyObject *name, *v, *v_cell;
+ int success = 0;
+ Py_ssize_t pos = 0;
+
+ v_cell = PyLong_FromLong(CELL);
+ if (!v_cell)
+ return 0;
+ while (PyDict_Next(scopes, &pos, &name, &v)) {
+ long scope;
+ assert(PyLong_Check(v));
+ scope = PyLong_AS_LONG(v);
+ if (scope != LOCAL)
+ continue;
+ if (!PySet_Contains(free, name))
+ continue;
+ /* Replace LOCAL with CELL for this name, and remove
+ from free. It is safe to replace the value of name
+ in the dict, because it will not cause a resize.
+ */
+ if (PyDict_SetItem(scopes, name, v_cell) < 0)
+ goto error;
+ if (PySet_Discard(free, name) < 0)
+ goto error;
+ }
+ success = 1;
+ error:
+ Py_DECREF(v_cell);
+ return success;
+}
+
+static int
+drop_class_free(PySTEntryObject *ste, PyObject *free)
+{
+ int res;
+ if (!GET_IDENTIFIER(__class__))
+ return 0;
+ res = PySet_Discard(free, __class__);
+ if (res < 0)
+ return 0;
+ if (res)
+ ste->ste_needs_class_closure = 1;
+ return 1;
+}
+
+/* Enter the final scope information into the ste_symbols dict.
+ *
+ * All arguments are dicts. Modifies symbols, others are read-only.
+*/
+static int
+update_symbols(PyObject *symbols, PyObject *scopes,
+ PyObject *bound, PyObject *free, int classflag)
+{
+ PyObject *name = NULL, *itr = NULL;
+ PyObject *v = NULL, *v_scope = NULL, *v_new = NULL, *v_free = NULL;
+ Py_ssize_t pos = 0;
+
+ /* Update scope information for all symbols in this scope */
+ while (PyDict_Next(symbols, &pos, &name, &v)) {
+ long scope, flags;
+ assert(PyLong_Check(v));
+ flags = PyLong_AS_LONG(v);
+ v_scope = PyDict_GetItem(scopes, name);
+ assert(v_scope && PyLong_Check(v_scope));
+ scope = PyLong_AS_LONG(v_scope);
+ flags |= (scope << SCOPE_OFFSET);
+ v_new = PyLong_FromLong(flags);
+ if (!v_new)
+ return 0;
+ if (PyDict_SetItem(symbols, name, v_new) < 0) {
+ Py_DECREF(v_new);
+ return 0;
+ }
+ Py_DECREF(v_new);
+ }
+
+ /* Record not yet resolved free variables from children (if any) */
+ v_free = PyLong_FromLong(FREE << SCOPE_OFFSET);
+ if (!v_free)
+ return 0;
+
+ itr = PyObject_GetIter(free);
+ if (itr == NULL) {
+ Py_DECREF(v_free);
+ return 0;
+ }
+
+ while ((name = PyIter_Next(itr))) {
+ v = PyDict_GetItemWithError(symbols, name);
+
+ /* Handle symbol that already exists in this scope */
+ if (v) {
+ /* Handle a free variable in a method of
+ the class that has the same name as a local
+ or global in the class scope.
+ */
+ if (classflag &&
+ PyLong_AS_LONG(v) & (DEF_BOUND | DEF_GLOBAL)) {
+ long flags = PyLong_AS_LONG(v) | DEF_FREE_CLASS;
+ v_new = PyLong_FromLong(flags);
+ if (!v_new) {
+ goto error;
+ }
+ if (PyDict_SetItem(symbols, name, v_new) < 0) {
+ Py_DECREF(v_new);
+ goto error;
+ }
+ Py_DECREF(v_new);
+ }
+ /* It's a cell, or already free in this scope */
+ Py_DECREF(name);
+ continue;
+ }
+ else if (PyErr_Occurred()) {
+ goto error;
+ }
+ /* Handle global symbol */
+ if (bound && !PySet_Contains(bound, name)) {
+ Py_DECREF(name);
+ continue; /* it's a global */
+ }
+ /* Propagate new free symbol up the lexical stack */
+ if (PyDict_SetItem(symbols, name, v_free) < 0) {
+ goto error;
+ }
+ Py_DECREF(name);
+ }
+ Py_DECREF(itr);
+ Py_DECREF(v_free);
+ return 1;
+error:
+ Py_XDECREF(v_free);
+ Py_XDECREF(itr);
+ Py_XDECREF(name);
+ return 0;
+}
+
+/* Make final symbol table decisions for block of ste.
+
+ Arguments:
+ ste -- current symtable entry (input/output)
+ bound -- set of variables bound in enclosing scopes (input). bound
+ is NULL for module blocks.
+ free -- set of free variables in enclosed scopes (output)
+ globals -- set of declared global variables in enclosing scopes (input)
+
+ The implementation uses two mutually recursive functions,
+ analyze_block() and analyze_child_block(). analyze_block() is
+ responsible for analyzing the individual names defined in a block.
+ analyze_child_block() prepares temporary namespace dictionaries
+ used to evaluated nested blocks.
+
+ The two functions exist because a child block should see the name
+ bindings of its enclosing blocks, but those bindings should not
+ propagate back to a parent block.
+*/
+
+static int
+analyze_child_block(PySTEntryObject *entry, PyObject *bound, PyObject *free,
+ PyObject *global, PyObject* child_free);
+
+static int
+analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
+ PyObject *global)
+{
+ PyObject *name, *v, *local = NULL, *scopes = NULL, *newbound = NULL;
+ PyObject *newglobal = NULL, *newfree = NULL, *allfree = NULL;
+ PyObject *temp;
+ int i, success = 0;
+ Py_ssize_t pos = 0;
+
+ local = PySet_New(NULL); /* collect new names bound in block */
+ if (!local)
+ goto error;
+ scopes = PyDict_New(); /* collect scopes defined for each name */
+ if (!scopes)
+ goto error;
+
+ /* Allocate new global and bound variable dictionaries. These
+ dictionaries hold the names visible in nested blocks. For
+ ClassBlocks, the bound and global names are initialized
+ before analyzing names, because class bindings aren't
+ visible in methods. For other blocks, they are initialized
+ after names are analyzed.
+ */
+
+ /* TODO(jhylton): Package these dicts in a struct so that we
+ can write reasonable helper functions?
+ */
+ newglobal = PySet_New(NULL);
+ if (!newglobal)
+ goto error;
+ newfree = PySet_New(NULL);
+ if (!newfree)
+ goto error;
+ newbound = PySet_New(NULL);
+ if (!newbound)
+ goto error;
+
+ /* Class namespace has no effect on names visible in
+ nested functions, so populate the global and bound
+ sets to be passed to child blocks before analyzing
+ this one.
+ */
+ if (ste->ste_type == ClassBlock) {
+ /* Pass down known globals */
+ temp = PyNumber_InPlaceOr(newglobal, global);
+ if (!temp)
+ goto error;
+ Py_DECREF(temp);
+ /* Pass down previously bound symbols */
+ if (bound) {
+ temp = PyNumber_InPlaceOr(newbound, bound);
+ if (!temp)
+ goto error;
+ Py_DECREF(temp);
+ }
+ }
+
+ while (PyDict_Next(ste->ste_symbols, &pos, &name, &v)) {
+ long flags = PyLong_AS_LONG(v);
+ if (!analyze_name(ste, scopes, name, flags,
+ bound, local, free, global))
+ goto error;
+ }
+
+ /* Populate global and bound sets to be passed to children. */
+ if (ste->ste_type != ClassBlock) {
+ /* Add function locals to bound set */
+ if (ste->ste_type == FunctionBlock) {
+ temp = PyNumber_InPlaceOr(newbound, local);
+ if (!temp)
+ goto error;
+ Py_DECREF(temp);
+ }
+ /* Pass down previously bound symbols */
+ if (bound) {
+ temp = PyNumber_InPlaceOr(newbound, bound);
+ if (!temp)
+ goto error;
+ Py_DECREF(temp);
+ }
+ /* Pass down known globals */
+ temp = PyNumber_InPlaceOr(newglobal, global);
+ if (!temp)
+ goto error;
+ Py_DECREF(temp);
+ }
+ else {
+ /* Special-case __class__ */
+ if (!GET_IDENTIFIER(__class__))
+ goto error;
+ if (PySet_Add(newbound, __class__) < 0)
+ goto error;
+ }
+
+ /* Recursively call analyze_child_block() on each child block.
+
+ newbound, newglobal now contain the names visible in
+ nested blocks. The free variables in the children will
+ be collected in allfree.
+ */
+ allfree = PySet_New(NULL);
+ if (!allfree)
+ goto error;
+ for (i = 0; i < PyList_GET_SIZE(ste->ste_children); ++i) {
+ PyObject *c = PyList_GET_ITEM(ste->ste_children, i);
+ PySTEntryObject* entry;
+ assert(c && PySTEntry_Check(c));
+ entry = (PySTEntryObject*)c;
+ if (!analyze_child_block(entry, newbound, newfree, newglobal,
+ allfree))
+ goto error;
+ /* Check if any children have free variables */
+ if (entry->ste_free || entry->ste_child_free)
+ ste->ste_child_free = 1;
+ }
+
+ temp = PyNumber_InPlaceOr(newfree, allfree);
+ if (!temp)
+ goto error;
+ Py_DECREF(temp);
+
+ /* Check if any local variables must be converted to cell variables */
+ if (ste->ste_type == FunctionBlock && !analyze_cells(scopes, newfree))
+ goto error;
+ else if (ste->ste_type == ClassBlock && !drop_class_free(ste, newfree))
+ goto error;
+ /* Records the results of the analysis in the symbol table entry */
+ if (!update_symbols(ste->ste_symbols, scopes, bound, newfree,
+ ste->ste_type == ClassBlock))
+ goto error;
+
+ temp = PyNumber_InPlaceOr(free, newfree);
+ if (!temp)
+ goto error;
+ Py_DECREF(temp);
+ success = 1;
+ error:
+ Py_XDECREF(scopes);
+ Py_XDECREF(local);
+ Py_XDECREF(newbound);
+ Py_XDECREF(newglobal);
+ Py_XDECREF(newfree);
+ Py_XDECREF(allfree);
+ if (!success)
+ assert(PyErr_Occurred());
+ return success;
+}
+
+static int
+analyze_child_block(PySTEntryObject *entry, PyObject *bound, PyObject *free,
+ PyObject *global, PyObject* child_free)
+{
+ PyObject *temp_bound = NULL, *temp_global = NULL, *temp_free = NULL;
+ PyObject *temp;
+
+ /* Copy the bound and global dictionaries.
+
+ These dictionaries are used by all blocks enclosed by the
+ current block. The analyze_block() call modifies these
+ dictionaries.
+
+ */
+ temp_bound = PySet_New(bound);
+ if (!temp_bound)
+ goto error;
+ temp_free = PySet_New(free);
+ if (!temp_free)
+ goto error;
+ temp_global = PySet_New(global);
+ if (!temp_global)
+ goto error;
+
+ if (!analyze_block(entry, temp_bound, temp_free, temp_global))
+ goto error;
+ temp = PyNumber_InPlaceOr(child_free, temp_free);
+ if (!temp)
+ goto error;
+ Py_DECREF(temp);
+ Py_DECREF(temp_bound);
+ Py_DECREF(temp_free);
+ Py_DECREF(temp_global);
+ return 1;
+ error:
+ Py_XDECREF(temp_bound);
+ Py_XDECREF(temp_free);
+ Py_XDECREF(temp_global);
+ return 0;
+}
+
+static int
+symtable_analyze(struct symtable *st)
+{
+ PyObject *free, *global;
+ int r;
+
+ free = PySet_New(NULL);
+ if (!free)
+ return 0;
+ global = PySet_New(NULL);
+ if (!global) {
+ Py_DECREF(free);
+ return 0;
+ }
+ r = analyze_block(st->st_top, NULL, free, global);
+ Py_DECREF(free);
+ Py_DECREF(global);
+ return r;
+}
+
+/* symtable_enter_block() gets a reference via ste_new.
+ This reference is released when the block is exited, via the DECREF
+ in symtable_exit_block().
+*/
+
+static int
+symtable_exit_block(struct symtable *st)
+{
+ Py_ssize_t size;
+
+ st->st_cur = NULL;
+ size = PyList_GET_SIZE(st->st_stack);
+ if (size) {
+ if (PyList_SetSlice(st->st_stack, size - 1, size, NULL) < 0)
+ return 0;
+ if (--size)
+ st->st_cur = (PySTEntryObject *)PyList_GET_ITEM(st->st_stack, size - 1);
+ }
+ return 1;
+}
+
+static int
+symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block,
+ void *ast, int lineno, int col_offset)
+{
+ PySTEntryObject *prev = NULL, *ste;
+
+ ste = ste_new(st, name, block, ast, lineno, col_offset);
+ if (ste == NULL)
+ return 0;
+ if (PyList_Append(st->st_stack, (PyObject *)ste) < 0) {
+ Py_DECREF(ste);
+ return 0;
+ }
+ prev = st->st_cur;
+ /* bpo-37757: For now, disallow *all* assignment expressions in the
+ * outermost iterator expression of a comprehension, even those inside
+ * a nested comprehension or a lambda expression.
+ */
+ if (prev) {
+ ste->ste_comp_iter_expr = prev->ste_comp_iter_expr;
+ }
+ /* The entry is owned by the stack. Borrow it for st_cur. */
+ Py_DECREF(ste);
+ st->st_cur = ste;
+ if (block == ModuleBlock)
+ st->st_global = st->st_cur->ste_symbols;
+ if (prev) {
+ if (PyList_Append(prev->ste_children, (PyObject *)ste) < 0) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static long
+symtable_lookup(struct symtable *st, PyObject *name)
+{
+ PyObject *mangled = _Py_Mangle(st->st_private, name);
+ if (!mangled)
+ return 0;
+ long ret = _PyST_GetSymbol(st->st_cur, mangled);
+ Py_DECREF(mangled);
+ return ret;
+}
+
+static int
+symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _symtable_entry *ste)
+{
+ PyObject *o;
+ PyObject *dict;
+ long val;
+ PyObject *mangled = _Py_Mangle(st->st_private, name);
+
+
+ if (!mangled)
+ return 0;
+ dict = ste->ste_symbols;
+ if ((o = PyDict_GetItemWithError(dict, mangled))) {
+ val = PyLong_AS_LONG(o);
+ if ((flag & DEF_PARAM) && (val & DEF_PARAM)) {
+ /* Is it better to use 'mangled' or 'name' here? */
+ PyErr_Format(PyExc_SyntaxError, DUPLICATE_ARGUMENT, name);
+ PyErr_SyntaxLocationObject(st->st_filename,
+ ste->ste_lineno,
+ ste->ste_col_offset + 1);
+ goto error;
+ }
+ val |= flag;
+ }
+ else if (PyErr_Occurred()) {
+ goto error;
+ }
+ else {
+ val = flag;
+ }
+ if (ste->ste_comp_iter_target) {
+ /* This name is an iteration variable in a comprehension,
+ * so check for a binding conflict with any named expressions.
+ * Otherwise, mark it as an iteration variable so subsequent
+ * named expressions can check for conflicts.
+ */
+ if (val & (DEF_GLOBAL | DEF_NONLOCAL)) {
+ PyErr_Format(PyExc_SyntaxError,
+ NAMED_EXPR_COMP_INNER_LOOP_CONFLICT, name);
+ PyErr_SyntaxLocationObject(st->st_filename,
+ ste->ste_lineno,
+ ste->ste_col_offset + 1);
+ goto error;
+ }
+ val |= DEF_COMP_ITER;
+ }
+ o = PyLong_FromLong(val);
+ if (o == NULL)
+ goto error;
+ if (PyDict_SetItem(dict, mangled, o) < 0) {
+ Py_DECREF(o);
+ goto error;
+ }
+ Py_DECREF(o);
+
+ if (flag & DEF_PARAM) {
+ if (PyList_Append(ste->ste_varnames, mangled) < 0)
+ goto error;
+ } else if (flag & DEF_GLOBAL) {
+ /* XXX need to update DEF_GLOBAL for other flags too;
+ perhaps only DEF_FREE_GLOBAL */
+ val = flag;
+ if ((o = PyDict_GetItem(st->st_global, mangled))) {
+ val |= PyLong_AS_LONG(o);
+ }
+ o = PyLong_FromLong(val);
+ if (o == NULL)
+ goto error;
+ if (PyDict_SetItem(st->st_global, mangled, o) < 0) {
+ Py_DECREF(o);
+ goto error;
+ }
+ Py_DECREF(o);
+ }
+ Py_DECREF(mangled);
+ return 1;
+
+error:
+ Py_DECREF(mangled);
+ return 0;
+}
+
+static int
+symtable_add_def(struct symtable *st, PyObject *name, int flag) {
+ return symtable_add_def_helper(st, name, flag, st->st_cur);
+}
+
+/* VISIT, VISIT_SEQ and VIST_SEQ_TAIL take an ASDL type as their second argument.
+ They use the ASDL name to synthesize the name of the C type and the visit
+ function.
+
+ VISIT_SEQ_TAIL permits the start of an ASDL sequence to be skipped, which is
+ useful if the first node in the sequence requires special treatment.
+
+ VISIT_QUIT macro returns the specified value exiting from the function but
+ first adjusts current recursion counter depth.
+*/
+
+#define VISIT_QUIT(ST, X) \
+ return --(ST)->recursion_depth,(X)
+
+#define VISIT(ST, TYPE, V) \
+ if (!symtable_visit_ ## TYPE((ST), (V))) \
+ VISIT_QUIT((ST), 0);
+
+#define VISIT_SEQ(ST, TYPE, SEQ) { \
+ int i; \
+ asdl_seq *seq = (SEQ); /* avoid variable capture */ \
+ for (i = 0; i < asdl_seq_LEN(seq); i++) { \
+ TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
+ if (!symtable_visit_ ## TYPE((ST), elt)) \
+ VISIT_QUIT((ST), 0); \
+ } \
+}
+
+#define VISIT_SEQ_TAIL(ST, TYPE, SEQ, START) { \
+ int i; \
+ asdl_seq *seq = (SEQ); /* avoid variable capture */ \
+ for (i = (START); i < asdl_seq_LEN(seq); i++) { \
+ TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
+ if (!symtable_visit_ ## TYPE((ST), elt)) \
+ VISIT_QUIT((ST), 0); \
+ } \
+}
+
+#define VISIT_SEQ_WITH_NULL(ST, TYPE, SEQ) { \
+ int i = 0; \
+ asdl_seq *seq = (SEQ); /* avoid variable capture */ \
+ for (i = 0; i < asdl_seq_LEN(seq); i++) { \
+ TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
+ if (!elt) continue; /* can be NULL */ \
+ if (!symtable_visit_ ## TYPE((ST), elt)) \
+ VISIT_QUIT((ST), 0); \
+ } \
+}
+
+static int
+symtable_record_directive(struct symtable *st, identifier name, int lineno, int col_offset)
+{
+ PyObject *data, *mangled;
+ int res;
+ if (!st->st_cur->ste_directives) {
+ st->st_cur->ste_directives = PyList_New(0);
+ if (!st->st_cur->ste_directives)
+ return 0;
+ }
+ mangled = _Py_Mangle(st->st_private, name);
+ if (!mangled)
+ return 0;
+ data = Py_BuildValue("(Nii)", mangled, lineno, col_offset);
+ if (!data)
+ return 0;
+ res = PyList_Append(st->st_cur->ste_directives, data);
+ Py_DECREF(data);
+ return res == 0;
+}
+
+
+static int
+symtable_visit_stmt(struct symtable *st, stmt_ty s)
+{
+ if (++st->recursion_depth > st->recursion_limit) {
+ PyErr_SetString(PyExc_RecursionError,
+ "maximum recursion depth exceeded during compilation");
+ VISIT_QUIT(st, 0);
+ }
+ switch (s->kind) {
+ case FunctionDef_kind:
+ if (!symtable_add_def(st, s->v.FunctionDef.name, DEF_LOCAL))
+ VISIT_QUIT(st, 0);
+ if (s->v.FunctionDef.args->defaults)
+ VISIT_SEQ(st, expr, s->v.FunctionDef.args->defaults);
+ if (s->v.FunctionDef.args->kw_defaults)
+ VISIT_SEQ_WITH_NULL(st, expr, s->v.FunctionDef.args->kw_defaults);
+ if (!symtable_visit_annotations(st, s->v.FunctionDef.args,
+ s->v.FunctionDef.returns))
+ VISIT_QUIT(st, 0);
+ if (s->v.FunctionDef.decorator_list)
+ VISIT_SEQ(st, expr, s->v.FunctionDef.decorator_list);
+ if (!symtable_enter_block(st, s->v.FunctionDef.name,
+ FunctionBlock, (void *)s, s->lineno,
+ s->col_offset))
+ VISIT_QUIT(st, 0);
+ VISIT(st, arguments, s->v.FunctionDef.args);
+ VISIT_SEQ(st, stmt, s->v.FunctionDef.body);
+ if (!symtable_exit_block(st))
+ VISIT_QUIT(st, 0);
+ break;
+ case ClassDef_kind: {
+ PyObject *tmp;
+ if (!symtable_add_def(st, s->v.ClassDef.name, DEF_LOCAL))
+ VISIT_QUIT(st, 0);
+ VISIT_SEQ(st, expr, s->v.ClassDef.bases);
+ VISIT_SEQ(st, keyword, s->v.ClassDef.keywords);
+ if (s->v.ClassDef.decorator_list)
+ VISIT_SEQ(st, expr, s->v.ClassDef.decorator_list);
+ if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock,
+ (void *)s, s->lineno, s->col_offset))
+ VISIT_QUIT(st, 0);
+ tmp = st->st_private;
+ st->st_private = s->v.ClassDef.name;
+ VISIT_SEQ(st, stmt, s->v.ClassDef.body);
+ st->st_private = tmp;
+ if (!symtable_exit_block(st))
+ VISIT_QUIT(st, 0);
+ break;
+ }
+ case Return_kind:
+ if (s->v.Return.value) {
+ VISIT(st, expr, s->v.Return.value);
+ st->st_cur->ste_returns_value = 1;
+ }
+ break;
+ case Delete_kind:
+ VISIT_SEQ(st, expr, s->v.Delete.targets);
+ break;
+ case Assign_kind:
+ VISIT_SEQ(st, expr, s->v.Assign.targets);
+ VISIT(st, expr, s->v.Assign.value);
+ break;
+ case AnnAssign_kind:
+ if (s->v.AnnAssign.target->kind == Name_kind) {
+ expr_ty e_name = s->v.AnnAssign.target;
+ long cur = symtable_lookup(st, e_name->v.Name.id);
+ if (cur < 0) {
+ VISIT_QUIT(st, 0);
+ }
+ if ((cur & (DEF_GLOBAL | DEF_NONLOCAL))
+ && (st->st_cur->ste_symbols != st->st_global)
+ && s->v.AnnAssign.simple) {
+ PyErr_Format(PyExc_SyntaxError,
+ cur & DEF_GLOBAL ? GLOBAL_ANNOT : NONLOCAL_ANNOT,
+ e_name->v.Name.id);
+ PyErr_SyntaxLocationObject(st->st_filename,
+ s->lineno,
+ s->col_offset + 1);
+ VISIT_QUIT(st, 0);
+ }
+ if (s->v.AnnAssign.simple &&
+ !symtable_add_def(st, e_name->v.Name.id,
+ DEF_ANNOT | DEF_LOCAL)) {
+ VISIT_QUIT(st, 0);
+ }
+ else {
+ if (s->v.AnnAssign.value
+ && !symtable_add_def(st, e_name->v.Name.id, DEF_LOCAL)) {
+ VISIT_QUIT(st, 0);
+ }
+ }
+ }
+ else {
+ VISIT(st, expr, s->v.AnnAssign.target);
+ }
+ VISIT(st, expr, s->v.AnnAssign.annotation);
+ if (s->v.AnnAssign.value) {
+ VISIT(st, expr, s->v.AnnAssign.value);
+ }
+ break;
+ case AugAssign_kind:
+ VISIT(st, expr, s->v.AugAssign.target);
+ VISIT(st, expr, s->v.AugAssign.value);
+ break;
+ case For_kind:
+ VISIT(st, expr, s->v.For.target);
+ VISIT(st, expr, s->v.For.iter);
+ VISIT_SEQ(st, stmt, s->v.For.body);
+ if (s->v.For.orelse)
+ VISIT_SEQ(st, stmt, s->v.For.orelse);
+ break;
+ case While_kind:
+ VISIT(st, expr, s->v.While.test);
+ VISIT_SEQ(st, stmt, s->v.While.body);
+ if (s->v.While.orelse)
+ VISIT_SEQ(st, stmt, s->v.While.orelse);
+ break;
+ case If_kind:
+ /* XXX if 0: and lookup_yield() hacks */
+ VISIT(st, expr, s->v.If.test);
+ VISIT_SEQ(st, stmt, s->v.If.body);
+ if (s->v.If.orelse)
+ VISIT_SEQ(st, stmt, s->v.If.orelse);
+ break;
+ case Raise_kind:
+ if (s->v.Raise.exc) {
+ VISIT(st, expr, s->v.Raise.exc);
+ if (s->v.Raise.cause) {
+ VISIT(st, expr, s->v.Raise.cause);
+ }
+ }
+ break;
+ case Try_kind:
+ VISIT_SEQ(st, stmt, s->v.Try.body);
+ VISIT_SEQ(st, stmt, s->v.Try.orelse);
+ VISIT_SEQ(st, excepthandler, s->v.Try.handlers);
+ VISIT_SEQ(st, stmt, s->v.Try.finalbody);
+ break;
+ case Assert_kind:
+ VISIT(st, expr, s->v.Assert.test);
+ if (s->v.Assert.msg)
+ VISIT(st, expr, s->v.Assert.msg);
+ break;
+ case Import_kind:
+ VISIT_SEQ(st, alias, s->v.Import.names);
+ break;
+ case ImportFrom_kind:
+ VISIT_SEQ(st, alias, s->v.ImportFrom.names);
+ break;
+ case Global_kind: {
+ int i;
+ asdl_seq *seq = s->v.Global.names;
+ for (i = 0; i < asdl_seq_LEN(seq); i++) {
+ identifier name = (identifier)asdl_seq_GET(seq, i);
+ long cur = symtable_lookup(st, name);
+ if (cur < 0)
+ VISIT_QUIT(st, 0);
+ if (cur & (DEF_PARAM | DEF_LOCAL | USE | DEF_ANNOT)) {
+ const char* msg;
+ if (cur & DEF_PARAM) {
+ msg = GLOBAL_PARAM;
+ } else if (cur & USE) {
+ msg = GLOBAL_AFTER_USE;
+ } else if (cur & DEF_ANNOT) {
+ msg = GLOBAL_ANNOT;
+ } else { /* DEF_LOCAL */
+ msg = GLOBAL_AFTER_ASSIGN;
+ }
+ PyErr_Format(PyExc_SyntaxError,
+ msg, name);
+ PyErr_SyntaxLocationObject(st->st_filename,
+ s->lineno,
+ s->col_offset + 1);
+ VISIT_QUIT(st, 0);
+ }
+ if (!symtable_add_def(st, name, DEF_GLOBAL))
+ VISIT_QUIT(st, 0);
+ if (!symtable_record_directive(st, name, s->lineno, s->col_offset))
+ VISIT_QUIT(st, 0);
+ }
+ break;
+ }
+ case Nonlocal_kind: {
+ int i;
+ asdl_seq *seq = s->v.Nonlocal.names;
+ for (i = 0; i < asdl_seq_LEN(seq); i++) {
+ identifier name = (identifier)asdl_seq_GET(seq, i);
+ long cur = symtable_lookup(st, name);
+ if (cur < 0)
+ VISIT_QUIT(st, 0);
+ if (cur & (DEF_PARAM | DEF_LOCAL | USE | DEF_ANNOT)) {
+ const char* msg;
+ if (cur & DEF_PARAM) {
+ msg = NONLOCAL_PARAM;
+ } else if (cur & USE) {
+ msg = NONLOCAL_AFTER_USE;
+ } else if (cur & DEF_ANNOT) {
+ msg = NONLOCAL_ANNOT;
+ } else { /* DEF_LOCAL */
+ msg = NONLOCAL_AFTER_ASSIGN;
+ }
+ PyErr_Format(PyExc_SyntaxError, msg, name);
+ PyErr_SyntaxLocationObject(st->st_filename,
+ s->lineno,
+ s->col_offset + 1);
+ VISIT_QUIT(st, 0);
+ }
+ if (!symtable_add_def(st, name, DEF_NONLOCAL))
+ VISIT_QUIT(st, 0);
+ if (!symtable_record_directive(st, name, s->lineno, s->col_offset))
+ VISIT_QUIT(st, 0);
+ }
+ break;
+ }
+ case Expr_kind:
+ VISIT(st, expr, s->v.Expr.value);
+ break;
+ case Pass_kind:
+ case Break_kind:
+ case Continue_kind:
+ /* nothing to do here */
+ break;
+ case With_kind:
+ VISIT_SEQ(st, withitem, s->v.With.items);
+ VISIT_SEQ(st, stmt, s->v.With.body);
+ break;
+ case AsyncFunctionDef_kind:
+ if (!symtable_add_def(st, s->v.AsyncFunctionDef.name, DEF_LOCAL))
+ VISIT_QUIT(st, 0);
+ if (s->v.AsyncFunctionDef.args->defaults)
+ VISIT_SEQ(st, expr, s->v.AsyncFunctionDef.args->defaults);
+ if (s->v.AsyncFunctionDef.args->kw_defaults)
+ VISIT_SEQ_WITH_NULL(st, expr,
+ s->v.AsyncFunctionDef.args->kw_defaults);
+ if (!symtable_visit_annotations(st, s->v.AsyncFunctionDef.args,
+ s->v.AsyncFunctionDef.returns))
+ VISIT_QUIT(st, 0);
+ if (s->v.AsyncFunctionDef.decorator_list)
+ VISIT_SEQ(st, expr, s->v.AsyncFunctionDef.decorator_list);
+ if (!symtable_enter_block(st, s->v.AsyncFunctionDef.name,
+ FunctionBlock, (void *)s, s->lineno,
+ s->col_offset))
+ VISIT_QUIT(st, 0);
+ st->st_cur->ste_coroutine = 1;
+ VISIT(st, arguments, s->v.AsyncFunctionDef.args);
+ VISIT_SEQ(st, stmt, s->v.AsyncFunctionDef.body);
+ if (!symtable_exit_block(st))
+ VISIT_QUIT(st, 0);
+ break;
+ case AsyncWith_kind:
+ VISIT_SEQ(st, withitem, s->v.AsyncWith.items);
+ VISIT_SEQ(st, stmt, s->v.AsyncWith.body);
+ break;
+ case AsyncFor_kind:
+ VISIT(st, expr, s->v.AsyncFor.target);
+ VISIT(st, expr, s->v.AsyncFor.iter);
+ VISIT_SEQ(st, stmt, s->v.AsyncFor.body);
+ if (s->v.AsyncFor.orelse)
+ VISIT_SEQ(st, stmt, s->v.AsyncFor.orelse);
+ break;
+ }
+ VISIT_QUIT(st, 1);
+}
+
+static int
+symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e)
+{
+ assert(st->st_stack);
+ assert(e->kind == Name_kind);
+
+ PyObject *target_name = e->v.Name.id;
+ Py_ssize_t i, size;
+ struct _symtable_entry *ste;
+ size = PyList_GET_SIZE(st->st_stack);
+ assert(size);
+
+ /* Iterate over the stack in reverse and add to the nearest adequate scope */
+ for (i = size - 1; i >= 0; i--) {
+ ste = (struct _symtable_entry *) PyList_GET_ITEM(st->st_stack, i);
+
+ /* If we find a comprehension scope, check for a target
+ * binding conflict with iteration variables, otherwise skip it
+ */
+ if (ste->ste_comprehension) {
+ long target_in_scope = _PyST_GetSymbol(ste, target_name);
+ if (target_in_scope & DEF_COMP_ITER) {
+ PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_CONFLICT, target_name);
+ PyErr_SyntaxLocationObject(st->st_filename,
+ e->lineno,
+ e->col_offset);
+ VISIT_QUIT(st, 0);
+ }
+ continue;
+ }
+
+ /* If we find a FunctionBlock entry, add as GLOBAL/LOCAL or NONLOCAL/LOCAL */
+ if (ste->ste_type == FunctionBlock) {
+ long target_in_scope = _PyST_GetSymbol(ste, target_name);
+ if (target_in_scope & DEF_GLOBAL) {
+ if (!symtable_add_def(st, target_name, DEF_GLOBAL))
+ VISIT_QUIT(st, 0);
+ } else {
+ if (!symtable_add_def(st, target_name, DEF_NONLOCAL))
+ VISIT_QUIT(st, 0);
+ }
+ if (!symtable_record_directive(st, target_name, e->lineno, e->col_offset))
+ VISIT_QUIT(st, 0);
+
+ return symtable_add_def_helper(st, target_name, DEF_LOCAL, ste);
+ }
+ /* If we find a ModuleBlock entry, add as GLOBAL */
+ if (ste->ste_type == ModuleBlock) {
+ if (!symtable_add_def(st, target_name, DEF_GLOBAL))
+ VISIT_QUIT(st, 0);
+ if (!symtable_record_directive(st, target_name, e->lineno, e->col_offset))
+ VISIT_QUIT(st, 0);
+
+ return symtable_add_def_helper(st, target_name, DEF_GLOBAL, ste);
+ }
+ /* Disallow usage in ClassBlock */
+ if (ste->ste_type == ClassBlock) {
+ PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_IN_CLASS);
+ PyErr_SyntaxLocationObject(st->st_filename,
+ e->lineno,
+ e->col_offset);
+ VISIT_QUIT(st, 0);
+ }
+ }
+
+ /* We should always find either a FunctionBlock, ModuleBlock or ClassBlock
+ and should never fall to this case
+ */
+ assert(0);
+ return 0;
+}
+
+static int
+symtable_handle_namedexpr(struct symtable *st, expr_ty e)
+{
+ if (st->st_cur->ste_comp_iter_expr > 0) {
+ /* Assignment isn't allowed in a comprehension iterable expression */
+ PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_ITER_EXPR);
+ PyErr_SyntaxLocationObject(st->st_filename,
+ e->lineno,
+ e->col_offset);
+ return 0;
+ }
+ if (st->st_cur->ste_comprehension) {
+ /* Inside a comprehension body, so find the right target scope */
+ if (!symtable_extend_namedexpr_scope(st, e->v.NamedExpr.target))
+ return 0;
+ }
+ VISIT(st, expr, e->v.NamedExpr.value);
+ VISIT(st, expr, e->v.NamedExpr.target);
+ return 1;
+}
+
+static int
+symtable_visit_expr(struct symtable *st, expr_ty e)
+{
+ if (++st->recursion_depth > st->recursion_limit) {
+ PyErr_SetString(PyExc_RecursionError,
+ "maximum recursion depth exceeded during compilation");
+ VISIT_QUIT(st, 0);
+ }
+ switch (e->kind) {
+ case NamedExpr_kind:
+ if(!symtable_handle_namedexpr(st, e))
+ VISIT_QUIT(st, 0);
+ break;
+ case BoolOp_kind:
+ VISIT_SEQ(st, expr, e->v.BoolOp.values);
+ break;
+ case BinOp_kind:
+ VISIT(st, expr, e->v.BinOp.left);
+ VISIT(st, expr, e->v.BinOp.right);
+ break;
+ case UnaryOp_kind:
+ VISIT(st, expr, e->v.UnaryOp.operand);
+ break;
+ case Lambda_kind: {
+ if (!GET_IDENTIFIER(lambda))
+ VISIT_QUIT(st, 0);
+ if (e->v.Lambda.args->defaults)
+ VISIT_SEQ(st, expr, e->v.Lambda.args->defaults);
+ if (e->v.Lambda.args->kw_defaults)
+ VISIT_SEQ_WITH_NULL(st, expr, e->v.Lambda.args->kw_defaults);
+ if (!symtable_enter_block(st, lambda,
+ FunctionBlock, (void *)e, e->lineno,
+ e->col_offset))
+ VISIT_QUIT(st, 0);
+ VISIT(st, arguments, e->v.Lambda.args);
+ VISIT(st, expr, e->v.Lambda.body);
+ if (!symtable_exit_block(st))
+ VISIT_QUIT(st, 0);
+ break;
+ }
+ case IfExp_kind:
+ VISIT(st, expr, e->v.IfExp.test);
+ VISIT(st, expr, e->v.IfExp.body);
+ VISIT(st, expr, e->v.IfExp.orelse);
+ break;
+ case Dict_kind:
+ VISIT_SEQ_WITH_NULL(st, expr, e->v.Dict.keys);
+ VISIT_SEQ(st, expr, e->v.Dict.values);
+ break;
+ case Set_kind:
+ VISIT_SEQ(st, expr, e->v.Set.elts);
+ break;
+ case GeneratorExp_kind:
+ if (!symtable_visit_genexp(st, e))
+ VISIT_QUIT(st, 0);
+ break;
+ case ListComp_kind:
+ if (!symtable_visit_listcomp(st, e))
+ VISIT_QUIT(st, 0);
+ break;
+ case SetComp_kind:
+ if (!symtable_visit_setcomp(st, e))
+ VISIT_QUIT(st, 0);
+ break;
+ case DictComp_kind:
+ if (!symtable_visit_dictcomp(st, e))
+ VISIT_QUIT(st, 0);
+ break;
+ case Yield_kind:
+ if (e->v.Yield.value)
+ VISIT(st, expr, e->v.Yield.value);
+ st->st_cur->ste_generator = 1;
+ break;
+ case YieldFrom_kind:
+ VISIT(st, expr, e->v.YieldFrom.value);
+ st->st_cur->ste_generator = 1;
+ break;
+ case Await_kind:
+ VISIT(st, expr, e->v.Await.value);
+ st->st_cur->ste_coroutine = 1;
+ break;
+ case Compare_kind:
+ VISIT(st, expr, e->v.Compare.left);
+ VISIT_SEQ(st, expr, e->v.Compare.comparators);
+ break;
+ case Call_kind:
+ VISIT(st, expr, e->v.Call.func);
+ VISIT_SEQ(st, expr, e->v.Call.args);
+ VISIT_SEQ_WITH_NULL(st, keyword, e->v.Call.keywords);
+ break;
+ case FormattedValue_kind:
+ VISIT(st, expr, e->v.FormattedValue.value);
+ if (e->v.FormattedValue.format_spec)
+ VISIT(st, expr, e->v.FormattedValue.format_spec);
+ break;
+ case JoinedStr_kind:
+ VISIT_SEQ(st, expr, e->v.JoinedStr.values);
+ break;
+ case Constant_kind:
+ /* Nothing to do here. */
+ break;
+ /* The following exprs can be assignment targets. */
+ case Attribute_kind:
+ VISIT(st, expr, e->v.Attribute.value);
+ break;
+ case Subscript_kind:
+ VISIT(st, expr, e->v.Subscript.value);
+ VISIT(st, expr, e->v.Subscript.slice);
+ break;
+ case Starred_kind:
+ VISIT(st, expr, e->v.Starred.value);
+ break;
+ case Slice_kind:
+ if (e->v.Slice.lower)
+ VISIT(st, expr, e->v.Slice.lower)
+ if (e->v.Slice.upper)
+ VISIT(st, expr, e->v.Slice.upper)
+ if (e->v.Slice.step)
+ VISIT(st, expr, e->v.Slice.step)
+ break;
+ case Name_kind:
+ if (!symtable_add_def(st, e->v.Name.id,
+ e->v.Name.ctx == Load ? USE : DEF_LOCAL))
+ VISIT_QUIT(st, 0);
+ /* Special-case super: it counts as a use of __class__ */
+ if (e->v.Name.ctx == Load &&
+ st->st_cur->ste_type == FunctionBlock &&
+ _PyUnicode_EqualToASCIIString(e->v.Name.id, "super")) {
+ if (!GET_IDENTIFIER(__class__) ||
+ !symtable_add_def(st, __class__, USE))
+ VISIT_QUIT(st, 0);
+ }
+ break;
+ /* child nodes of List and Tuple will have expr_context set */
+ case List_kind:
+ VISIT_SEQ(st, expr, e->v.List.elts);
+ break;
+ case Tuple_kind:
+ VISIT_SEQ(st, expr, e->v.Tuple.elts);
+ break;
+ }
+ VISIT_QUIT(st, 1);
+}
+
+static int
+symtable_implicit_arg(struct symtable *st, int pos)
+{
+ PyObject *id = PyUnicode_FromFormat(".%d", pos);
+ if (id == NULL)
+ return 0;
+ if (!symtable_add_def(st, id, DEF_PARAM)) {
+ Py_DECREF(id);
+ return 0;
+ }
+ Py_DECREF(id);
+ return 1;
+}
+
+static int
+symtable_visit_params(struct symtable *st, asdl_seq *args)
+{
+ int i;
+
+ if (!args)
+ return -1;
+
+ for (i = 0; i < asdl_seq_LEN(args); i++) {
+ arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
+ if (!symtable_add_def(st, arg->arg, DEF_PARAM))
+ return 0;
+ }
+
+ return 1;
+}
+
+static int
+symtable_visit_argannotations(struct symtable *st, asdl_seq *args)
+{
+ int i;
+
+ if (!args)
+ return -1;
+
+ for (i = 0; i < asdl_seq_LEN(args); i++) {
+ arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
+ if (arg->annotation)
+ VISIT(st, expr, arg->annotation);
+ }
+
+ return 1;
+}
+
+static int
+symtable_visit_annotations(struct symtable *st, arguments_ty a, expr_ty returns)
+{
+ if (a->posonlyargs && !symtable_visit_argannotations(st, a->posonlyargs))
+ return 0;
+ if (a->args && !symtable_visit_argannotations(st, a->args))
+ return 0;
+ if (a->vararg && a->vararg->annotation)
+ VISIT(st, expr, a->vararg->annotation);
+ if (a->kwarg && a->kwarg->annotation)
+ VISIT(st, expr, a->kwarg->annotation);
+ if (a->kwonlyargs && !symtable_visit_argannotations(st, a->kwonlyargs))
+ return 0;
+ if (returns)
+ VISIT(st, expr, returns);
+ return 1;
+}
+
+static int
+symtable_visit_arguments(struct symtable *st, arguments_ty a)
+{
+ /* skip default arguments inside function block
+ XXX should ast be different?
+ */
+ if (a->posonlyargs && !symtable_visit_params(st, a->posonlyargs))
+ return 0;
+ if (a->args && !symtable_visit_params(st, a->args))
+ return 0;
+ if (a->kwonlyargs && !symtable_visit_params(st, a->kwonlyargs))
+ return 0;
+ if (a->vararg) {
+ if (!symtable_add_def(st, a->vararg->arg, DEF_PARAM))
+ return 0;
+ st->st_cur->ste_varargs = 1;
+ }
+ if (a->kwarg) {
+ if (!symtable_add_def(st, a->kwarg->arg, DEF_PARAM))
+ return 0;
+ st->st_cur->ste_varkeywords = 1;
+ }
+ return 1;
+}
+
+
+static int
+symtable_visit_excepthandler(struct symtable *st, excepthandler_ty eh)
+{
+ if (eh->v.ExceptHandler.type)
+ VISIT(st, expr, eh->v.ExceptHandler.type);
+ if (eh->v.ExceptHandler.name)
+ if (!symtable_add_def(st, eh->v.ExceptHandler.name, DEF_LOCAL))
+ return 0;
+ VISIT_SEQ(st, stmt, eh->v.ExceptHandler.body);
+ return 1;
+}
+
+static int
+symtable_visit_withitem(struct symtable *st, withitem_ty item)
+{
+ VISIT(st, expr, item->context_expr);
+ if (item->optional_vars) {
+ VISIT(st, expr, item->optional_vars);
+ }
+ return 1;
+}
+
+
+static int
+symtable_visit_alias(struct symtable *st, alias_ty a)
+{
+ /* Compute store_name, the name actually bound by the import
+ operation. It is different than a->name when a->name is a
+ dotted package name (e.g. spam.eggs)
+ */
+ PyObject *store_name;
+ PyObject *name = (a->asname == NULL) ? a->name : a->asname;
+ Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0,
+ PyUnicode_GET_LENGTH(name), 1);
+ if (dot != -1) {
+ store_name = PyUnicode_Substring(name, 0, dot);
+ if (!store_name)
+ return 0;
+ }
+ else {
+ store_name = name;
+ Py_INCREF(store_name);
+ }
+ if (!_PyUnicode_EqualToASCIIString(name, "*")) {
+ int r = symtable_add_def(st, store_name, DEF_IMPORT);
+ Py_DECREF(store_name);
+ return r;
+ }
+ else {
+ if (st->st_cur->ste_type != ModuleBlock) {
+ int lineno = st->st_cur->ste_lineno;
+ int col_offset = st->st_cur->ste_col_offset;
+ PyErr_SetString(PyExc_SyntaxError, IMPORT_STAR_WARNING);
+ PyErr_SyntaxLocationObject(st->st_filename, lineno, col_offset + 1);
+ Py_DECREF(store_name);
+ return 0;
+ }
+ Py_DECREF(store_name);
+ return 1;
+ }
+}
+
+
+static int
+symtable_visit_comprehension(struct symtable *st, comprehension_ty lc)
+{
+ st->st_cur->ste_comp_iter_target = 1;
+ VISIT(st, expr, lc->target);
+ st->st_cur->ste_comp_iter_target = 0;
+ st->st_cur->ste_comp_iter_expr++;
+ VISIT(st, expr, lc->iter);
+ st->st_cur->ste_comp_iter_expr--;
+ VISIT_SEQ(st, expr, lc->ifs);
+ if (lc->is_async) {
+ st->st_cur->ste_coroutine = 1;
+ }
+ return 1;
+}
+
+
+static int
+symtable_visit_keyword(struct symtable *st, keyword_ty k)
+{
+ VISIT(st, expr, k->value);
+ return 1;
+}
+
+
+static int
+symtable_handle_comprehension(struct symtable *st, expr_ty e,
+ identifier scope_name, asdl_seq *generators,
+ expr_ty elt, expr_ty value)
+{
+ int is_generator = (e->kind == GeneratorExp_kind);
+ comprehension_ty outermost = ((comprehension_ty)
+ asdl_seq_GET(generators, 0));
+ /* Outermost iterator is evaluated in current scope */
+ st->st_cur->ste_comp_iter_expr++;
+ VISIT(st, expr, outermost->iter);
+ st->st_cur->ste_comp_iter_expr--;
+ /* Create comprehension scope for the rest */
+ if (!scope_name ||
+ !symtable_enter_block(st, scope_name, FunctionBlock, (void *)e,
+ e->lineno, e->col_offset)) {
+ return 0;
+ }
+ if (outermost->is_async) {
+ st->st_cur->ste_coroutine = 1;
+ }
+ st->st_cur->ste_comprehension = 1;
+
+ /* Outermost iter is received as an argument */
+ if (!symtable_implicit_arg(st, 0)) {
+ symtable_exit_block(st);
+ return 0;
+ }
+ /* Visit iteration variable target, and mark them as such */
+ st->st_cur->ste_comp_iter_target = 1;
+ VISIT(st, expr, outermost->target);
+ st->st_cur->ste_comp_iter_target = 0;
+ /* Visit the rest of the comprehension body */
+ VISIT_SEQ(st, expr, outermost->ifs);
+ VISIT_SEQ_TAIL(st, comprehension, generators, 1);
+ if (value)
+ VISIT(st, expr, value);
+ VISIT(st, expr, elt);
+ if (st->st_cur->ste_generator) {
+ PyErr_SetString(PyExc_SyntaxError,
+ (e->kind == ListComp_kind) ? "'yield' inside list comprehension" :
+ (e->kind == SetComp_kind) ? "'yield' inside set comprehension" :
+ (e->kind == DictComp_kind) ? "'yield' inside dict comprehension" :
+ "'yield' inside generator expression");
+ PyErr_SyntaxLocationObject(st->st_filename,
+ st->st_cur->ste_lineno,
+ st->st_cur->ste_col_offset + 1);
+ symtable_exit_block(st);
+ return 0;
+ }
+ st->st_cur->ste_generator = is_generator;
+ return symtable_exit_block(st);
+}
+
+static int
+symtable_visit_genexp(struct symtable *st, expr_ty e)
+{
+ return symtable_handle_comprehension(st, e, GET_IDENTIFIER(genexpr),
+ e->v.GeneratorExp.generators,
+ e->v.GeneratorExp.elt, NULL);
+}
+
+static int
+symtable_visit_listcomp(struct symtable *st, expr_ty e)
+{
+ return symtable_handle_comprehension(st, e, GET_IDENTIFIER(listcomp),
+ e->v.ListComp.generators,
+ e->v.ListComp.elt, NULL);
+}
+
+static int
+symtable_visit_setcomp(struct symtable *st, expr_ty e)
+{
+ return symtable_handle_comprehension(st, e, GET_IDENTIFIER(setcomp),
+ e->v.SetComp.generators,
+ e->v.SetComp.elt, NULL);
+}
+
+static int
+symtable_visit_dictcomp(struct symtable *st, expr_ty e)
+{
+ return symtable_handle_comprehension(st, e, GET_IDENTIFIER(dictcomp),
+ e->v.DictComp.generators,
+ e->v.DictComp.key,
+ e->v.DictComp.value);
+}
diff --git a/contrib/tools/python3/src/Python/sysmodule.c b/contrib/tools/python3/src/Python/sysmodule.c
new file mode 100644
index 00000000000..33eb848fac3
--- /dev/null
+++ b/contrib/tools/python3/src/Python/sysmodule.c
@@ -0,0 +1,3327 @@
+
+/* System module */
+
+/*
+Various bits of information used by the interpreter are collected in
+module 'sys'.
+Function member:
+- exit(sts): raise SystemExit
+Data members:
+- stdin, stdout, stderr: standard file objects
+- modules: the table of modules (dictionary)
+- path: module search path (list of strings)
+- argv: script arguments (list of strings)
+- ps1, ps2: optional primary and secondary prompts (strings)
+*/
+
+#include "Python.h"
+#include "code.h"
+#include "frameobject.h" // PyFrame_GetBack()
+#include "pycore_ceval.h"
+#include "pycore_initconfig.h"
+#include "pycore_object.h"
+#include "pycore_pathconfig.h"
+#include "pycore_pyerrors.h"
+#include "pycore_pylifecycle.h"
+#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
+#include "pycore_pystate.h" // _PyThreadState_GET()
+#include "pycore_tupleobject.h"
+
+#include "pydtrace.h"
+#include "osdefs.h" // DELIM
+#include <locale.h>
+
+#ifdef MS_WINDOWS
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif /* MS_WINDOWS */
+
+#ifdef MS_COREDLL
+extern void *PyWin_DLLhModule;
+/* A string loaded from the DLL at startup: */
+extern const char *PyWin_DLLVersionString;
+#endif
+
+/*[clinic input]
+module sys
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3726b388feee8cea]*/
+
+#include "clinic/sysmodule.c.h"
+
+_Py_IDENTIFIER(_);
+_Py_IDENTIFIER(__sizeof__);
+_Py_IDENTIFIER(_xoptions);
+_Py_IDENTIFIER(buffer);
+_Py_IDENTIFIER(builtins);
+_Py_IDENTIFIER(encoding);
+_Py_IDENTIFIER(path);
+_Py_IDENTIFIER(stdout);
+_Py_IDENTIFIER(stderr);
+_Py_IDENTIFIER(warnoptions);
+_Py_IDENTIFIER(write);
+
+static PyObject *
+sys_get_object_id(PyThreadState *tstate, _Py_Identifier *key)
+{
+ PyObject *sd = tstate->interp->sysdict;
+ if (sd == NULL) {
+ return NULL;
+ }
+ return _PyDict_GetItemId(sd, key);
+}
+
+PyObject *
+_PySys_GetObjectId(_Py_Identifier *key)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ return sys_get_object_id(tstate, key);
+}
+
+PyObject *
+PySys_GetObject(const char *name)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyObject *sd = tstate->interp->sysdict;
+ if (sd == NULL) {
+ return NULL;
+ }
+ return PyDict_GetItemString(sd, name);
+}
+
+static int
+sys_set_object_id(PyThreadState *tstate, _Py_Identifier *key, PyObject *v)
+{
+ PyObject *sd = tstate->interp->sysdict;
+ if (v == NULL) {
+ if (_PyDict_GetItemId(sd, key) == NULL) {
+ return 0;
+ }
+ else {
+ return _PyDict_DelItemId(sd, key);
+ }
+ }
+ else {
+ return _PyDict_SetItemId(sd, key, v);
+ }
+}
+
+int
+_PySys_SetObjectId(_Py_Identifier *key, PyObject *v)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ return sys_set_object_id(tstate, key, v);
+}
+
+static int
+sys_set_object(PyThreadState *tstate, const char *name, PyObject *v)
+{
+ PyObject *sd = tstate->interp->sysdict;
+ if (v == NULL) {
+ if (PyDict_GetItemString(sd, name) == NULL) {
+ return 0;
+ }
+ else {
+ return PyDict_DelItemString(sd, name);
+ }
+ }
+ else {
+ return PyDict_SetItemString(sd, name, v);
+ }
+}
+
+int
+PySys_SetObject(const char *name, PyObject *v)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ return sys_set_object(tstate, name, v);
+}
+
+
+static int
+should_audit(PyInterpreterState *is)
+{
+ /* tstate->interp cannot be NULL, but test it just in case
+ for extra safety */
+ assert(is != NULL);
+ if (!is) {
+ return 0;
+ }
+ return (is->runtime->audit_hook_head
+ || is->audit_hooks
+ || PyDTrace_AUDIT_ENABLED());
+}
+
+
+static int
+sys_audit_tstate(PyThreadState *ts, const char *event,
+ const char *argFormat, va_list vargs)
+{
+ /* N format is inappropriate, because you do not know
+ whether the reference is consumed by the call.
+ Assert rather than exception for perf reasons */
+ assert(!argFormat || !strchr(argFormat, 'N'));
+
+ if (!ts) {
+ /* Audit hooks cannot be called with a NULL thread state */
+ return 0;
+ }
+
+ /* The current implementation cannot be called if tstate is not
+ the current Python thread state. */
+ assert(ts == _PyThreadState_GET());
+
+ /* Early exit when no hooks are registered */
+ PyInterpreterState *is = ts->interp;
+ if (!should_audit(is)) {
+ return 0;
+ }
+
+ PyObject *eventName = NULL;
+ PyObject *eventArgs = NULL;
+ PyObject *hooks = NULL;
+ PyObject *hook = NULL;
+ int res = -1;
+
+ int dtrace = PyDTrace_AUDIT_ENABLED();
+
+ PyObject *exc_type, *exc_value, *exc_tb;
+ _PyErr_Fetch(ts, &exc_type, &exc_value, &exc_tb);
+
+ /* Initialize event args now */
+ if (argFormat && argFormat[0]) {
+ eventArgs = _Py_VaBuildValue_SizeT(argFormat, vargs);
+ if (eventArgs && !PyTuple_Check(eventArgs)) {
+ PyObject *argTuple = PyTuple_Pack(1, eventArgs);
+ Py_DECREF(eventArgs);
+ eventArgs = argTuple;
+ }
+ }
+ else {
+ eventArgs = PyTuple_New(0);
+ }
+ if (!eventArgs) {
+ goto exit;
+ }
+
+ /* Call global hooks */
+ _Py_AuditHookEntry *e = is->runtime->audit_hook_head;
+ for (; e; e = e->next) {
+ if (e->hookCFunction(event, eventArgs, e->userData) < 0) {
+ goto exit;
+ }
+ }
+
+ /* Dtrace USDT point */
+ if (dtrace) {
+ PyDTrace_AUDIT(event, (void *)eventArgs);
+ }
+
+ /* Call interpreter hooks */
+ if (is->audit_hooks) {
+ eventName = PyUnicode_FromString(event);
+ if (!eventName) {
+ goto exit;
+ }
+
+ hooks = PyObject_GetIter(is->audit_hooks);
+ if (!hooks) {
+ goto exit;
+ }
+
+ /* Disallow tracing in hooks unless explicitly enabled */
+ ts->tracing++;
+ ts->use_tracing = 0;
+ while ((hook = PyIter_Next(hooks)) != NULL) {
+ _Py_IDENTIFIER(__cantrace__);
+ PyObject *o;
+ int canTrace = _PyObject_LookupAttrId(hook, &PyId___cantrace__, &o);
+ if (o) {
+ canTrace = PyObject_IsTrue(o);
+ Py_DECREF(o);
+ }
+ if (canTrace < 0) {
+ break;
+ }
+ if (canTrace) {
+ ts->use_tracing = (ts->c_tracefunc || ts->c_profilefunc);
+ ts->tracing--;
+ }
+ PyObject* args[2] = {eventName, eventArgs};
+ o = _PyObject_FastCallTstate(ts, hook, args, 2);
+ if (canTrace) {
+ ts->tracing++;
+ ts->use_tracing = 0;
+ }
+ if (!o) {
+ break;
+ }
+ Py_DECREF(o);
+ Py_CLEAR(hook);
+ }
+ ts->use_tracing = (ts->c_tracefunc || ts->c_profilefunc);
+ ts->tracing--;
+ if (_PyErr_Occurred(ts)) {
+ goto exit;
+ }
+ }
+
+ res = 0;
+
+exit:
+ Py_XDECREF(hook);
+ Py_XDECREF(hooks);
+ Py_XDECREF(eventName);
+ Py_XDECREF(eventArgs);
+
+ if (!res) {
+ _PyErr_Restore(ts, exc_type, exc_value, exc_tb);
+ }
+ else {
+ assert(_PyErr_Occurred(ts));
+ Py_XDECREF(exc_type);
+ Py_XDECREF(exc_value);
+ Py_XDECREF(exc_tb);
+ }
+
+ return res;
+}
+
+int
+_PySys_Audit(PyThreadState *tstate, const char *event,
+ const char *argFormat, ...)
+{
+ va_list vargs;
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, argFormat);
+#else
+ va_start(vargs);
+#endif
+ int res = sys_audit_tstate(tstate, event, argFormat, vargs);
+ va_end(vargs);
+ return res;
+}
+
+int
+PySys_Audit(const char *event, const char *argFormat, ...)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ va_list vargs;
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, argFormat);
+#else
+ va_start(vargs);
+#endif
+ int res = sys_audit_tstate(tstate, event, argFormat, vargs);
+ va_end(vargs);
+ return res;
+}
+
+/* We expose this function primarily for our own cleanup during
+ * finalization. In general, it should not need to be called,
+ * and as such the function is not exported.
+ *
+ * Must be finalizing to clear hooks */
+void
+_PySys_ClearAuditHooks(PyThreadState *ts)
+{
+ assert(ts != NULL);
+ if (!ts) {
+ return;
+ }
+
+ _PyRuntimeState *runtime = ts->interp->runtime;
+ PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(runtime);
+ assert(finalizing == ts);
+ if (finalizing != ts) {
+ return;
+ }
+
+ const PyConfig *config = _PyInterpreterState_GetConfig(ts->interp);
+ if (config->verbose) {
+ PySys_WriteStderr("# clear sys.audit hooks\n");
+ }
+
+ /* Hooks can abort later hooks for this event, but cannot
+ abort the clear operation itself. */
+ _PySys_Audit(ts, "cpython._PySys_ClearAuditHooks", NULL);
+ _PyErr_Clear(ts);
+
+ _Py_AuditHookEntry *e = runtime->audit_hook_head, *n;
+ runtime->audit_hook_head = NULL;
+ while (e) {
+ n = e->next;
+ PyMem_RawFree(e);
+ e = n;
+ }
+}
+
+int
+PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
+{
+ /* tstate can be NULL, so access directly _PyRuntime:
+ PySys_AddAuditHook() can be called before Python is initialized. */
+ _PyRuntimeState *runtime = &_PyRuntime;
+ PyThreadState *tstate;
+ if (runtime->initialized) {
+ tstate = _PyRuntimeState_GetThreadState(runtime);
+ }
+ else {
+ tstate = NULL;
+ }
+
+ /* Invoke existing audit hooks to allow them an opportunity to abort. */
+ /* Cannot invoke hooks until we are initialized */
+ if (tstate != NULL) {
+ if (_PySys_Audit(tstate, "sys.addaudithook", NULL) < 0) {
+ if (_PyErr_ExceptionMatches(tstate, PyExc_RuntimeError)) {
+ /* We do not report errors derived from RuntimeError */
+ _PyErr_Clear(tstate);
+ return 0;
+ }
+ return -1;
+ }
+ }
+
+ _Py_AuditHookEntry *e = runtime->audit_hook_head;
+ if (!e) {
+ e = (_Py_AuditHookEntry*)PyMem_RawMalloc(sizeof(_Py_AuditHookEntry));
+ runtime->audit_hook_head = e;
+ } else {
+ while (e->next) {
+ e = e->next;
+ }
+ e = e->next = (_Py_AuditHookEntry*)PyMem_RawMalloc(
+ sizeof(_Py_AuditHookEntry));
+ }
+
+ if (!e) {
+ if (tstate != NULL) {
+ _PyErr_NoMemory(tstate);
+ }
+ return -1;
+ }
+
+ e->next = NULL;
+ e->hookCFunction = (Py_AuditHookFunction)hook;
+ e->userData = userData;
+
+ return 0;
+}
+
+/*[clinic input]
+sys.addaudithook
+
+ hook: object
+
+Adds a new audit hook callback.
+[clinic start generated code]*/
+
+static PyObject *
+sys_addaudithook_impl(PyObject *module, PyObject *hook)
+/*[clinic end generated code: output=4f9c17aaeb02f44e input=0f3e191217a45e34]*/
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+
+ /* Invoke existing audit hooks to allow them an opportunity to abort. */
+ if (_PySys_Audit(tstate, "sys.addaudithook", NULL) < 0) {
+ if (_PyErr_ExceptionMatches(tstate, PyExc_Exception)) {
+ /* We do not report errors derived from Exception */
+ _PyErr_Clear(tstate);
+ Py_RETURN_NONE;
+ }
+ return NULL;
+ }
+
+ PyInterpreterState *is = tstate->interp;
+ if (is->audit_hooks == NULL) {
+ is->audit_hooks = PyList_New(0);
+ if (is->audit_hooks == NULL) {
+ return NULL;
+ }
+ }
+
+ if (PyList_Append(is->audit_hooks, hook) < 0) {
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(audit_doc,
+"audit(event, *args)\n\
+\n\
+Passes the event to any audit hooks that are attached.");
+
+static PyObject *
+sys_audit(PyObject *self, PyObject *const *args, Py_ssize_t argc)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ _Py_EnsureTstateNotNULL(tstate);
+
+ if (argc == 0) {
+ _PyErr_SetString(tstate, PyExc_TypeError,
+ "audit() missing 1 required positional argument: "
+ "'event'");
+ return NULL;
+ }
+
+ if (!should_audit(tstate->interp)) {
+ Py_RETURN_NONE;
+ }
+
+ PyObject *auditEvent = args[0];
+ if (!auditEvent) {
+ _PyErr_SetString(tstate, PyExc_TypeError,
+ "expected str for argument 'event'");
+ return NULL;
+ }
+ if (!PyUnicode_Check(auditEvent)) {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "expected str for argument 'event', not %.200s",
+ Py_TYPE(auditEvent)->tp_name);
+ return NULL;
+ }
+ const char *event = PyUnicode_AsUTF8(auditEvent);
+ if (!event) {
+ return NULL;
+ }
+
+ PyObject *auditArgs = _PyTuple_FromArray(args + 1, argc - 1);
+ if (!auditArgs) {
+ return NULL;
+ }
+
+ int res = _PySys_Audit(tstate, event, "O", auditArgs);
+ Py_DECREF(auditArgs);
+
+ if (res < 0) {
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
+
+static PyObject *
+sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ assert(!_PyErr_Occurred(tstate));
+ char *envar = Py_GETENV("PYTHONBREAKPOINT");
+
+ if (envar == NULL || strlen(envar) == 0) {
+ envar = "pdb.set_trace";
+ }
+ else if (!strcmp(envar, "0")) {
+ /* The breakpoint is explicitly no-op'd. */
+ Py_RETURN_NONE;
+ }
+ /* According to POSIX the string returned by getenv() might be invalidated
+ * or the string content might be overwritten by a subsequent call to
+ * getenv(). Since importing a module can performs the getenv() calls,
+ * we need to save a copy of envar. */
+ envar = _PyMem_RawStrdup(envar);
+ if (envar == NULL) {
+ _PyErr_NoMemory(tstate);
+ return NULL;
+ }
+ const char *last_dot = strrchr(envar, '.');
+ const char *attrname = NULL;
+ PyObject *modulepath = NULL;
+
+ if (last_dot == NULL) {
+ /* The breakpoint is a built-in, e.g. PYTHONBREAKPOINT=int */
+ modulepath = PyUnicode_FromString("builtins");
+ attrname = envar;
+ }
+ else if (last_dot != envar) {
+ /* Split on the last dot; */
+ modulepath = PyUnicode_FromStringAndSize(envar, last_dot - envar);
+ attrname = last_dot + 1;
+ }
+ else {
+ goto warn;
+ }
+ if (modulepath == NULL) {
+ PyMem_RawFree(envar);
+ return NULL;
+ }
+
+ PyObject *module = PyImport_Import(modulepath);
+ Py_DECREF(modulepath);
+
+ if (module == NULL) {
+ if (_PyErr_ExceptionMatches(tstate, PyExc_ImportError)) {
+ goto warn;
+ }
+ PyMem_RawFree(envar);
+ return NULL;
+ }
+
+ PyObject *hook = PyObject_GetAttrString(module, attrname);
+ Py_DECREF(module);
+
+ if (hook == NULL) {
+ if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) {
+ goto warn;
+ }
+ PyMem_RawFree(envar);
+ return NULL;
+ }
+ PyMem_RawFree(envar);
+ PyObject *retval = PyObject_Vectorcall(hook, args, nargs, keywords);
+ Py_DECREF(hook);
+ return retval;
+
+ warn:
+ /* If any of the imports went wrong, then warn and ignore. */
+ _PyErr_Clear(tstate);
+ int status = PyErr_WarnFormat(
+ PyExc_RuntimeWarning, 0,
+ "Ignoring unimportable $PYTHONBREAKPOINT: \"%s\"", envar);
+ PyMem_RawFree(envar);
+ if (status < 0) {
+ /* Printing the warning raised an exception. */
+ return NULL;
+ }
+ /* The warning was (probably) issued. */
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(breakpointhook_doc,
+"breakpointhook(*args, **kws)\n"
+"\n"
+"This hook function is called by built-in breakpoint().\n"
+);
+
+/* Write repr(o) to sys.stdout using sys.stdout.encoding and 'backslashreplace'
+ error handler. If sys.stdout has a buffer attribute, use
+ sys.stdout.buffer.write(encoded), otherwise redecode the string and use
+ sys.stdout.write(redecoded).
+
+ Helper function for sys_displayhook(). */
+static int
+sys_displayhook_unencodable(PyObject *outf, PyObject *o)
+{
+ PyObject *stdout_encoding = NULL;
+ PyObject *encoded, *escaped_str, *repr_str, *buffer, *result;
+ const char *stdout_encoding_str;
+ int ret;
+
+ stdout_encoding = _PyObject_GetAttrId(outf, &PyId_encoding);
+ if (stdout_encoding == NULL)
+ goto error;
+ stdout_encoding_str = PyUnicode_AsUTF8(stdout_encoding);
+ if (stdout_encoding_str == NULL)
+ goto error;
+
+ repr_str = PyObject_Repr(o);
+ if (repr_str == NULL)
+ goto error;
+ encoded = PyUnicode_AsEncodedString(repr_str,
+ stdout_encoding_str,
+ "backslashreplace");
+ Py_DECREF(repr_str);
+ if (encoded == NULL)
+ goto error;
+
+ if (_PyObject_LookupAttrId(outf, &PyId_buffer, &buffer) < 0) {
+ Py_DECREF(encoded);
+ goto error;
+ }
+ if (buffer) {
+ result = _PyObject_CallMethodIdOneArg(buffer, &PyId_write, encoded);
+ Py_DECREF(buffer);
+ Py_DECREF(encoded);
+ if (result == NULL)
+ goto error;
+ Py_DECREF(result);
+ }
+ else {
+ escaped_str = PyUnicode_FromEncodedObject(encoded,
+ stdout_encoding_str,
+ "strict");
+ Py_DECREF(encoded);
+ if (PyFile_WriteObject(escaped_str, outf, Py_PRINT_RAW) != 0) {
+ Py_DECREF(escaped_str);
+ goto error;
+ }
+ Py_DECREF(escaped_str);
+ }
+ ret = 0;
+ goto finally;
+
+error:
+ ret = -1;
+finally:
+ Py_XDECREF(stdout_encoding);
+ return ret;
+}
+
+/*[clinic input]
+sys.displayhook
+
+ object as o: object
+ /
+
+Print an object to sys.stdout and also save it in builtins._
+[clinic start generated code]*/
+
+static PyObject *
+sys_displayhook(PyObject *module, PyObject *o)
+/*[clinic end generated code: output=347477d006df92ed input=08ba730166d7ef72]*/
+{
+ PyObject *outf;
+ PyObject *builtins;
+ static PyObject *newline = NULL;
+ PyThreadState *tstate = _PyThreadState_GET();
+
+ builtins = _PyImport_GetModuleId(&PyId_builtins);
+ if (builtins == NULL) {
+ if (!_PyErr_Occurred(tstate)) {
+ _PyErr_SetString(tstate, PyExc_RuntimeError,
+ "lost builtins module");
+ }
+ return NULL;
+ }
+ Py_DECREF(builtins);
+
+ /* Print value except if None */
+ /* After printing, also assign to '_' */
+ /* Before, set '_' to None to avoid recursion */
+ if (o == Py_None) {
+ Py_RETURN_NONE;
+ }
+ if (_PyObject_SetAttrId(builtins, &PyId__, Py_None) != 0)
+ return NULL;
+ outf = sys_get_object_id(tstate, &PyId_stdout);
+ if (outf == NULL || outf == Py_None) {
+ _PyErr_SetString(tstate, PyExc_RuntimeError, "lost sys.stdout");
+ return NULL;
+ }
+ if (PyFile_WriteObject(o, outf, 0) != 0) {
+ if (_PyErr_ExceptionMatches(tstate, PyExc_UnicodeEncodeError)) {
+ int err;
+ /* repr(o) is not encodable to sys.stdout.encoding with
+ * sys.stdout.errors error handler (which is probably 'strict') */
+ _PyErr_Clear(tstate);
+ err = sys_displayhook_unencodable(outf, o);
+ if (err) {
+ return NULL;
+ }
+ }
+ else {
+ return NULL;
+ }
+ }
+ if (newline == NULL) {
+ newline = PyUnicode_FromString("\n");
+ if (newline == NULL)
+ return NULL;
+ }
+ if (PyFile_WriteObject(newline, outf, Py_PRINT_RAW) != 0)
+ return NULL;
+ if (_PyObject_SetAttrId(builtins, &PyId__, o) != 0)
+ return NULL;
+ Py_RETURN_NONE;
+}
+
+
+/*[clinic input]
+sys.excepthook
+
+ exctype: object
+ value: object
+ traceback: object
+ /
+
+Handle an exception by displaying it with a traceback on sys.stderr.
+[clinic start generated code]*/
+
+static PyObject *
+sys_excepthook_impl(PyObject *module, PyObject *exctype, PyObject *value,
+ PyObject *traceback)
+/*[clinic end generated code: output=18d99fdda21b6b5e input=ecf606fa826f19d9]*/
+{
+ PyErr_Display(exctype, value, traceback);
+ Py_RETURN_NONE;
+}
+
+
+/*[clinic input]
+sys.exc_info
+
+Return current exception information: (type, value, traceback).
+
+Return information about the most recent exception caught by an except
+clause in the current stack frame or in an older stack frame.
+[clinic start generated code]*/
+
+static PyObject *
+sys_exc_info_impl(PyObject *module)
+/*[clinic end generated code: output=3afd0940cf3a4d30 input=b5c5bf077788a3e5]*/
+{
+ _PyErr_StackItem *err_info = _PyErr_GetTopmostException(_PyThreadState_GET());
+ return Py_BuildValue(
+ "(OOO)",
+ err_info->exc_type != NULL ? err_info->exc_type : Py_None,
+ err_info->exc_value != NULL ? err_info->exc_value : Py_None,
+ err_info->exc_traceback != NULL ?
+ err_info->exc_traceback : Py_None);
+}
+
+
+/*[clinic input]
+sys.unraisablehook
+
+ unraisable: object
+ /
+
+Handle an unraisable exception.
+
+The unraisable argument has the following attributes:
+
+* exc_type: Exception type.
+* exc_value: Exception value, can be None.
+* exc_traceback: Exception traceback, can be None.
+* err_msg: Error message, can be None.
+* object: Object causing the exception, can be None.
+[clinic start generated code]*/
+
+static PyObject *
+sys_unraisablehook(PyObject *module, PyObject *unraisable)
+/*[clinic end generated code: output=bb92838b32abaa14 input=ec3af148294af8d3]*/
+{
+ return _PyErr_WriteUnraisableDefaultHook(unraisable);
+}
+
+
+/*[clinic input]
+sys.exit
+
+ status: object = None
+ /
+
+Exit the interpreter by raising SystemExit(status).
+
+If the status is omitted or None, it defaults to zero (i.e., success).
+If the status is an integer, it will be used as the system exit status.
+If it is another kind of object, it will be printed and the system
+exit status will be one (i.e., failure).
+[clinic start generated code]*/
+
+static PyObject *
+sys_exit_impl(PyObject *module, PyObject *status)
+/*[clinic end generated code: output=13870986c1ab2ec0 input=b86ca9497baa94f2]*/
+{
+ /* Raise SystemExit so callers may catch it or clean up. */
+ PyThreadState *tstate = _PyThreadState_GET();
+ _PyErr_SetObject(tstate, PyExc_SystemExit, status);
+ return NULL;
+}
+
+
+
+/*[clinic input]
+sys.getdefaultencoding
+
+Return the current default encoding used by the Unicode implementation.
+[clinic start generated code]*/
+
+static PyObject *
+sys_getdefaultencoding_impl(PyObject *module)
+/*[clinic end generated code: output=256d19dfcc0711e6 input=d416856ddbef6909]*/
+{
+ return PyUnicode_FromString(PyUnicode_GetDefaultEncoding());
+}
+
+/*[clinic input]
+sys.getfilesystemencoding
+
+Return the encoding used to convert Unicode filenames to OS filenames.
+[clinic start generated code]*/
+
+static PyObject *
+sys_getfilesystemencoding_impl(PyObject *module)
+/*[clinic end generated code: output=1dc4bdbe9be44aa7 input=8475f8649b8c7d8c]*/
+{
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ const PyConfig *config = _PyInterpreterState_GetConfig(interp);
+ return PyUnicode_FromWideChar(config->filesystem_encoding, -1);
+}
+
+/*[clinic input]
+sys.getfilesystemencodeerrors
+
+Return the error mode used Unicode to OS filename conversion.
+[clinic start generated code]*/
+
+static PyObject *
+sys_getfilesystemencodeerrors_impl(PyObject *module)
+/*[clinic end generated code: output=ba77b36bbf7c96f5 input=22a1e8365566f1e5]*/
+{
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ const PyConfig *config = _PyInterpreterState_GetConfig(interp);
+ return PyUnicode_FromWideChar(config->filesystem_errors, -1);
+}
+
+/*[clinic input]
+sys.intern
+
+ string as s: unicode
+ /
+
+``Intern'' the given string.
+
+This enters the string in the (global) table of interned strings whose
+purpose is to speed up dictionary lookups. Return the string itself or
+the previously interned string object with the same value.
+[clinic start generated code]*/
+
+static PyObject *
+sys_intern_impl(PyObject *module, PyObject *s)
+/*[clinic end generated code: output=be680c24f5c9e5d6 input=849483c006924e2f]*/
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (PyUnicode_CheckExact(s)) {
+ Py_INCREF(s);
+ PyUnicode_InternInPlace(&s);
+ return s;
+ }
+ else {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "can't intern %.400s", Py_TYPE(s)->tp_name);
+ return NULL;
+ }
+}
+
+
+/*
+ * Cached interned string objects used for calling the profile and
+ * trace functions. Initialized by trace_init().
+ */
+static PyObject *whatstrings[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+
+static int
+trace_init(void)
+{
+ static const char * const whatnames[8] = {
+ "call", "exception", "line", "return",
+ "c_call", "c_exception", "c_return",
+ "opcode"
+ };
+ PyObject *name;
+ int i;
+ for (i = 0; i < 8; ++i) {
+ if (whatstrings[i] == NULL) {
+ name = PyUnicode_InternFromString(whatnames[i]);
+ if (name == NULL)
+ return -1;
+ whatstrings[i] = name;
+ }
+ }
+ return 0;
+}
+
+
+static PyObject *
+call_trampoline(PyThreadState *tstate, PyObject* callback,
+ PyFrameObject *frame, int what, PyObject *arg)
+{
+ if (PyFrame_FastToLocalsWithError(frame) < 0) {
+ return NULL;
+ }
+
+ PyObject *stack[3];
+ stack[0] = (PyObject *)frame;
+ stack[1] = whatstrings[what];
+ stack[2] = (arg != NULL) ? arg : Py_None;
+
+ /* call the Python-level function */
+ PyObject *result = _PyObject_FastCallTstate(tstate, callback, stack, 3);
+
+ PyFrame_LocalsToFast(frame, 1);
+ if (result == NULL) {
+ PyTraceBack_Here(frame);
+ }
+
+ return result;
+}
+
+static int
+profile_trampoline(PyObject *self, PyFrameObject *frame,
+ int what, PyObject *arg)
+{
+ if (arg == NULL) {
+ arg = Py_None;
+ }
+
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyObject *result = call_trampoline(tstate, self, frame, what, arg);
+ if (result == NULL) {
+ _PyEval_SetProfile(tstate, NULL, NULL);
+ return -1;
+ }
+
+ Py_DECREF(result);
+ return 0;
+}
+
+static int
+trace_trampoline(PyObject *self, PyFrameObject *frame,
+ int what, PyObject *arg)
+{
+ PyObject *callback;
+ if (what == PyTrace_CALL) {
+ callback = self;
+ }
+ else {
+ callback = frame->f_trace;
+ }
+ if (callback == NULL) {
+ return 0;
+ }
+
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyObject *result = call_trampoline(tstate, callback, frame, what, arg);
+ if (result == NULL) {
+ _PyEval_SetTrace(tstate, NULL, NULL);
+ Py_CLEAR(frame->f_trace);
+ return -1;
+ }
+
+ if (result != Py_None) {
+ Py_XSETREF(frame->f_trace, result);
+ }
+ else {
+ Py_DECREF(result);
+ }
+ return 0;
+}
+
+static PyObject *
+sys_settrace(PyObject *self, PyObject *args)
+{
+ if (trace_init() == -1) {
+ return NULL;
+ }
+
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (args == Py_None) {
+ if (_PyEval_SetTrace(tstate, NULL, NULL) < 0) {
+ return NULL;
+ }
+ }
+ else {
+ if (_PyEval_SetTrace(tstate, trace_trampoline, args) < 0) {
+ return NULL;
+ }
+ }
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(settrace_doc,
+"settrace(function)\n\
+\n\
+Set the global debug tracing function. It will be called on each\n\
+function call. See the debugger chapter in the library manual."
+);
+
+/*[clinic input]
+sys.gettrace
+
+Return the global debug tracing function set with sys.settrace.
+
+See the debugger chapter in the library manual.
+[clinic start generated code]*/
+
+static PyObject *
+sys_gettrace_impl(PyObject *module)
+/*[clinic end generated code: output=e97e3a4d8c971b6e input=373b51bb2147f4d8]*/
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyObject *temp = tstate->c_traceobj;
+
+ if (temp == NULL)
+ temp = Py_None;
+ Py_INCREF(temp);
+ return temp;
+}
+
+static PyObject *
+sys_setprofile(PyObject *self, PyObject *args)
+{
+ if (trace_init() == -1) {
+ return NULL;
+ }
+
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (args == Py_None) {
+ if (_PyEval_SetProfile(tstate, NULL, NULL) < 0) {
+ return NULL;
+ }
+ }
+ else {
+ if (_PyEval_SetProfile(tstate, profile_trampoline, args) < 0) {
+ return NULL;
+ }
+ }
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(setprofile_doc,
+"setprofile(function)\n\
+\n\
+Set the profiling function. It will be called on each function call\n\
+and return. See the profiler chapter in the library manual."
+);
+
+/*[clinic input]
+sys.getprofile
+
+Return the profiling function set with sys.setprofile.
+
+See the profiler chapter in the library manual.
+[clinic start generated code]*/
+
+static PyObject *
+sys_getprofile_impl(PyObject *module)
+/*[clinic end generated code: output=579b96b373448188 input=1b3209d89a32965d]*/
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyObject *temp = tstate->c_profileobj;
+
+ if (temp == NULL)
+ temp = Py_None;
+ Py_INCREF(temp);
+ return temp;
+}
+
+
+/*[clinic input]
+sys.setswitchinterval
+
+ interval: double
+ /
+
+Set the ideal thread switching delay inside the Python interpreter.
+
+The actual frequency of switching threads can be lower if the
+interpreter executes long sequences of uninterruptible code
+(this is implementation-specific and workload-dependent).
+
+The parameter must represent the desired switching delay in seconds
+A typical value is 0.005 (5 milliseconds).
+[clinic start generated code]*/
+
+static PyObject *
+sys_setswitchinterval_impl(PyObject *module, double interval)
+/*[clinic end generated code: output=65a19629e5153983 input=561b477134df91d9]*/
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (interval <= 0.0) {
+ _PyErr_SetString(tstate, PyExc_ValueError,
+ "switch interval must be strictly positive");
+ return NULL;
+ }
+ _PyEval_SetSwitchInterval((unsigned long) (1e6 * interval));
+ Py_RETURN_NONE;
+}
+
+
+/*[clinic input]
+sys.getswitchinterval -> double
+
+Return the current thread switch interval; see sys.setswitchinterval().
+[clinic start generated code]*/
+
+static double
+sys_getswitchinterval_impl(PyObject *module)
+/*[clinic end generated code: output=a38c277c85b5096d input=bdf9d39c0ebbbb6f]*/
+{
+ return 1e-6 * _PyEval_GetSwitchInterval();
+}
+
+/*[clinic input]
+sys.setrecursionlimit
+
+ limit as new_limit: int
+ /
+
+Set the maximum depth of the Python interpreter stack to n.
+
+This limit prevents infinite recursion from causing an overflow of the C
+stack and crashing Python. The highest possible limit is platform-
+dependent.
+[clinic start generated code]*/
+
+static PyObject *
+sys_setrecursionlimit_impl(PyObject *module, int new_limit)
+/*[clinic end generated code: output=35e1c64754800ace input=b0f7a23393924af3]*/
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+
+ if (new_limit < 1) {
+ _PyErr_SetString(tstate, PyExc_ValueError,
+ "recursion limit must be greater or equal than 1");
+ return NULL;
+ }
+
+ /* Issue #25274: When the recursion depth hits the recursion limit in
+ _Py_CheckRecursiveCall(), the overflowed flag of the thread state is
+ set to 1 and a RecursionError is raised. The overflowed flag is reset
+ to 0 when the recursion depth goes below the low-water mark: see
+ Py_LeaveRecursiveCall().
+
+ Reject too low new limit if the current recursion depth is higher than
+ the new low-water mark. Otherwise it may not be possible anymore to
+ reset the overflowed flag to 0. */
+ if (tstate->recursion_depth >= new_limit) {
+ _PyErr_Format(tstate, PyExc_RecursionError,
+ "cannot set the recursion limit to %i at "
+ "the recursion depth %i: the limit is too low",
+ new_limit, tstate->recursion_depth);
+ return NULL;
+ }
+
+ Py_SetRecursionLimit(new_limit);
+ Py_RETURN_NONE;
+}
+
+/*[clinic input]
+sys.set_coroutine_origin_tracking_depth
+
+ depth: int
+
+Enable or disable origin tracking for coroutine objects in this thread.
+
+Coroutine objects will track 'depth' frames of traceback information
+about where they came from, available in their cr_origin attribute.
+
+Set a depth of 0 to disable.
+[clinic start generated code]*/
+
+static PyObject *
+sys_set_coroutine_origin_tracking_depth_impl(PyObject *module, int depth)
+/*[clinic end generated code: output=0a2123c1cc6759c5 input=a1d0a05f89d2c426]*/
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (depth < 0) {
+ _PyErr_SetString(tstate, PyExc_ValueError, "depth must be >= 0");
+ return NULL;
+ }
+ _PyEval_SetCoroutineOriginTrackingDepth(tstate, depth);
+ Py_RETURN_NONE;
+}
+
+/*[clinic input]
+sys.get_coroutine_origin_tracking_depth -> int
+
+Check status of origin tracking for coroutine objects in this thread.
+[clinic start generated code]*/
+
+static int
+sys_get_coroutine_origin_tracking_depth_impl(PyObject *module)
+/*[clinic end generated code: output=3699f7be95a3afb8 input=335266a71205b61a]*/
+{
+ return _PyEval_GetCoroutineOriginTrackingDepth();
+}
+
+static PyTypeObject AsyncGenHooksType;
+
+PyDoc_STRVAR(asyncgen_hooks_doc,
+"asyncgen_hooks\n\
+\n\
+A named tuple providing information about asynchronous\n\
+generators hooks. The attributes are read only.");
+
+static PyStructSequence_Field asyncgen_hooks_fields[] = {
+ {"firstiter", "Hook to intercept first iteration"},
+ {"finalizer", "Hook to intercept finalization"},
+ {0}
+};
+
+static PyStructSequence_Desc asyncgen_hooks_desc = {
+ "asyncgen_hooks", /* name */
+ asyncgen_hooks_doc, /* doc */
+ asyncgen_hooks_fields , /* fields */
+ 2
+};
+
+static PyObject *
+sys_set_asyncgen_hooks(PyObject *self, PyObject *args, PyObject *kw)
+{
+ static char *keywords[] = {"firstiter", "finalizer", NULL};
+ PyObject *firstiter = NULL;
+ PyObject *finalizer = NULL;
+ PyThreadState *tstate = _PyThreadState_GET();
+
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kw, "|OO", keywords,
+ &firstiter, &finalizer)) {
+ return NULL;
+ }
+
+ if (finalizer && finalizer != Py_None) {
+ if (!PyCallable_Check(finalizer)) {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "callable finalizer expected, got %.50s",
+ Py_TYPE(finalizer)->tp_name);
+ return NULL;
+ }
+ if (_PyEval_SetAsyncGenFinalizer(finalizer) < 0) {
+ return NULL;
+ }
+ }
+ else if (finalizer == Py_None && _PyEval_SetAsyncGenFinalizer(NULL) < 0) {
+ return NULL;
+ }
+
+ if (firstiter && firstiter != Py_None) {
+ if (!PyCallable_Check(firstiter)) {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "callable firstiter expected, got %.50s",
+ Py_TYPE(firstiter)->tp_name);
+ return NULL;
+ }
+ if (_PyEval_SetAsyncGenFirstiter(firstiter) < 0) {
+ return NULL;
+ }
+ }
+ else if (firstiter == Py_None && _PyEval_SetAsyncGenFirstiter(NULL) < 0) {
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(set_asyncgen_hooks_doc,
+"set_asyncgen_hooks(* [, firstiter] [, finalizer])\n\
+\n\
+Set a finalizer for async generators objects."
+);
+
+/*[clinic input]
+sys.get_asyncgen_hooks
+
+Return the installed asynchronous generators hooks.
+
+This returns a namedtuple of the form (firstiter, finalizer).
+[clinic start generated code]*/
+
+static PyObject *
+sys_get_asyncgen_hooks_impl(PyObject *module)
+/*[clinic end generated code: output=53a253707146f6cf input=3676b9ea62b14625]*/
+{
+ PyObject *res;
+ PyObject *firstiter = _PyEval_GetAsyncGenFirstiter();
+ PyObject *finalizer = _PyEval_GetAsyncGenFinalizer();
+
+ res = PyStructSequence_New(&AsyncGenHooksType);
+ if (res == NULL) {
+ return NULL;
+ }
+
+ if (firstiter == NULL) {
+ firstiter = Py_None;
+ }
+
+ if (finalizer == NULL) {
+ finalizer = Py_None;
+ }
+
+ Py_INCREF(firstiter);
+ PyStructSequence_SET_ITEM(res, 0, firstiter);
+
+ Py_INCREF(finalizer);
+ PyStructSequence_SET_ITEM(res, 1, finalizer);
+
+ return res;
+}
+
+
+static PyTypeObject Hash_InfoType;
+
+PyDoc_STRVAR(hash_info_doc,
+"hash_info\n\
+\n\
+A named tuple providing parameters used for computing\n\
+hashes. The attributes are read only.");
+
+static PyStructSequence_Field hash_info_fields[] = {
+ {"width", "width of the type used for hashing, in bits"},
+ {"modulus", "prime number giving the modulus on which the hash "
+ "function is based"},
+ {"inf", "value to be used for hash of a positive infinity"},
+ {"nan", "value to be used for hash of a nan"},
+ {"imag", "multiplier used for the imaginary part of a complex number"},
+ {"algorithm", "name of the algorithm for hashing of str, bytes and "
+ "memoryviews"},
+ {"hash_bits", "internal output size of hash algorithm"},
+ {"seed_bits", "seed size of hash algorithm"},
+ {"cutoff", "small string optimization cutoff"},
+ {NULL, NULL}
+};
+
+static PyStructSequence_Desc hash_info_desc = {
+ "sys.hash_info",
+ hash_info_doc,
+ hash_info_fields,
+ 9,
+};
+
+static PyObject *
+get_hash_info(PyThreadState *tstate)
+{
+ PyObject *hash_info;
+ int field = 0;
+ PyHash_FuncDef *hashfunc;
+ hash_info = PyStructSequence_New(&Hash_InfoType);
+ if (hash_info == NULL)
+ return NULL;
+ hashfunc = PyHash_GetFuncDef();
+ PyStructSequence_SET_ITEM(hash_info, field++,
+ PyLong_FromLong(8*sizeof(Py_hash_t)));
+ PyStructSequence_SET_ITEM(hash_info, field++,
+ PyLong_FromSsize_t(_PyHASH_MODULUS));
+ PyStructSequence_SET_ITEM(hash_info, field++,
+ PyLong_FromLong(_PyHASH_INF));
+ PyStructSequence_SET_ITEM(hash_info, field++,
+ PyLong_FromLong(_PyHASH_NAN));
+ PyStructSequence_SET_ITEM(hash_info, field++,
+ PyLong_FromLong(_PyHASH_IMAG));
+ PyStructSequence_SET_ITEM(hash_info, field++,
+ PyUnicode_FromString(hashfunc->name));
+ PyStructSequence_SET_ITEM(hash_info, field++,
+ PyLong_FromLong(hashfunc->hash_bits));
+ PyStructSequence_SET_ITEM(hash_info, field++,
+ PyLong_FromLong(hashfunc->seed_bits));
+ PyStructSequence_SET_ITEM(hash_info, field++,
+ PyLong_FromLong(Py_HASH_CUTOFF));
+ if (_PyErr_Occurred(tstate)) {
+ Py_CLEAR(hash_info);
+ return NULL;
+ }
+ return hash_info;
+}
+/*[clinic input]
+sys.getrecursionlimit
+
+Return the current value of the recursion limit.
+
+The recursion limit is the maximum depth of the Python interpreter
+stack. This limit prevents infinite recursion from causing an overflow
+of the C stack and crashing Python.
+[clinic start generated code]*/
+
+static PyObject *
+sys_getrecursionlimit_impl(PyObject *module)
+/*[clinic end generated code: output=d571fb6b4549ef2e input=1c6129fd2efaeea8]*/
+{
+ return PyLong_FromLong(Py_GetRecursionLimit());
+}
+
+#ifdef MS_WINDOWS
+
+static PyTypeObject WindowsVersionType = {0, 0, 0, 0, 0, 0};
+
+static PyStructSequence_Field windows_version_fields[] = {
+ {"major", "Major version number"},
+ {"minor", "Minor version number"},
+ {"build", "Build number"},
+ {"platform", "Operating system platform"},
+ {"service_pack", "Latest Service Pack installed on the system"},
+ {"service_pack_major", "Service Pack major version number"},
+ {"service_pack_minor", "Service Pack minor version number"},
+ {"suite_mask", "Bit mask identifying available product suites"},
+ {"product_type", "System product type"},
+ {"platform_version", "Diagnostic version number"},
+ {0}
+};
+
+static PyStructSequence_Desc windows_version_desc = {
+ "sys.getwindowsversion", /* name */
+ sys_getwindowsversion__doc__, /* doc */
+ windows_version_fields, /* fields */
+ 5 /* For backward compatibility,
+ only the first 5 items are accessible
+ via indexing, the rest are name only */
+};
+
+/* Disable deprecation warnings about GetVersionEx as the result is
+ being passed straight through to the caller, who is responsible for
+ using it correctly. */
+#pragma warning(push)
+#pragma warning(disable:4996)
+
+/*[clinic input]
+sys.getwindowsversion
+
+Return info about the running version of Windows as a named tuple.
+
+The members are named: major, minor, build, platform, service_pack,
+service_pack_major, service_pack_minor, suite_mask, product_type and
+platform_version. For backward compatibility, only the first 5 items
+are available by indexing. All elements are numbers, except
+service_pack and platform_type which are strings, and platform_version
+which is a 3-tuple. Platform is always 2. Product_type may be 1 for a
+workstation, 2 for a domain controller, 3 for a server.
+Platform_version is a 3-tuple containing a version number that is
+intended for identifying the OS rather than feature detection.
+[clinic start generated code]*/
+
+static PyObject *
+sys_getwindowsversion_impl(PyObject *module)
+/*[clinic end generated code: output=1ec063280b932857 input=73a228a328fee63a]*/
+{
+ PyObject *version;
+ int pos = 0;
+ OSVERSIONINFOEXW ver;
+ DWORD realMajor, realMinor, realBuild;
+ HANDLE hKernel32;
+ wchar_t kernel32_path[MAX_PATH];
+ LPVOID verblock;
+ DWORD verblock_size;
+ PyThreadState *tstate = _PyThreadState_GET();
+
+ ver.dwOSVersionInfoSize = sizeof(ver);
+ if (!GetVersionExW((OSVERSIONINFOW*) &ver))
+ return PyErr_SetFromWindowsErr(0);
+
+ version = PyStructSequence_New(&WindowsVersionType);
+ if (version == NULL)
+ return NULL;
+
+ PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwMajorVersion));
+ PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwMinorVersion));
+ PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwBuildNumber));
+ PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwPlatformId));
+ PyStructSequence_SET_ITEM(version, pos++, PyUnicode_FromWideChar(ver.szCSDVersion, -1));
+ PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wServicePackMajor));
+ PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wServicePackMinor));
+ PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wSuiteMask));
+ PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wProductType));
+
+ realMajor = ver.dwMajorVersion;
+ realMinor = ver.dwMinorVersion;
+ realBuild = ver.dwBuildNumber;
+
+ // GetVersion will lie if we are running in a compatibility mode.
+ // We need to read the version info from a system file resource
+ // to accurately identify the OS version. If we fail for any reason,
+ // just return whatever GetVersion said.
+ Py_BEGIN_ALLOW_THREADS
+ hKernel32 = GetModuleHandleW(L"kernel32.dll");
+ Py_END_ALLOW_THREADS
+ if (hKernel32 && GetModuleFileNameW(hKernel32, kernel32_path, MAX_PATH) &&
+ (verblock_size = GetFileVersionInfoSizeExW(0, kernel32_path, NULL)) &&
+ (verblock = PyMem_RawMalloc(verblock_size))) {
+ VS_FIXEDFILEINFO *ffi;
+ UINT ffi_len;
+
+ if (GetFileVersionInfoExW(0, kernel32_path, 0, verblock_size, verblock) &&
+ VerQueryValueW(verblock, L"", (LPVOID)&ffi, &ffi_len)) {
+ realMajor = HIWORD(ffi->dwProductVersionMS);
+ realMinor = LOWORD(ffi->dwProductVersionMS);
+ realBuild = HIWORD(ffi->dwProductVersionLS);
+ }
+ PyMem_RawFree(verblock);
+ }
+ PyStructSequence_SET_ITEM(version, pos++, Py_BuildValue("(kkk)",
+ realMajor,
+ realMinor,
+ realBuild
+ ));
+
+ if (_PyErr_Occurred(tstate)) {
+ Py_DECREF(version);
+ return NULL;
+ }
+
+ return version;
+}
+
+#pragma warning(pop)
+
+/*[clinic input]
+sys._enablelegacywindowsfsencoding
+
+Changes the default filesystem encoding to mbcs:replace.
+
+This is done for consistency with earlier versions of Python. See PEP
+529 for more information.
+
+This is equivalent to defining the PYTHONLEGACYWINDOWSFSENCODING
+environment variable before launching Python.
+[clinic start generated code]*/
+
+static PyObject *
+sys__enablelegacywindowsfsencoding_impl(PyObject *module)
+/*[clinic end generated code: output=f5c3855b45e24fe9 input=2bfa931a20704492]*/
+{
+ if (_PyUnicode_EnableLegacyWindowsFSEncoding() < 0) {
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+#endif /* MS_WINDOWS */
+
+#ifdef HAVE_DLOPEN
+
+/*[clinic input]
+sys.setdlopenflags
+
+ flags as new_val: int
+ /
+
+Set the flags used by the interpreter for dlopen calls.
+
+This is used, for example, when the interpreter loads extension
+modules. Among other things, this will enable a lazy resolving of
+symbols when importing a module, if called as sys.setdlopenflags(0).
+To share symbols across extension modules, call as
+sys.setdlopenflags(os.RTLD_GLOBAL). Symbolic names for the flag
+modules can be found in the os module (RTLD_xxx constants, e.g.
+os.RTLD_LAZY).
+[clinic start generated code]*/
+
+static PyObject *
+sys_setdlopenflags_impl(PyObject *module, int new_val)
+/*[clinic end generated code: output=ec918b7fe0a37281 input=4c838211e857a77f]*/
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ tstate->interp->dlopenflags = new_val;
+ Py_RETURN_NONE;
+}
+
+
+/*[clinic input]
+sys.getdlopenflags
+
+Return the current value of the flags that are used for dlopen calls.
+
+The flag constants are defined in the os module.
+[clinic start generated code]*/
+
+static PyObject *
+sys_getdlopenflags_impl(PyObject *module)
+/*[clinic end generated code: output=e92cd1bc5005da6e input=dc4ea0899c53b4b6]*/
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ return PyLong_FromLong(tstate->interp->dlopenflags);
+}
+
+#endif /* HAVE_DLOPEN */
+
+#ifdef USE_MALLOPT
+/* Link with -lmalloc (or -lmpc) on an SGI */
+#include <malloc.h>
+
+/*[clinic input]
+sys.mdebug
+
+ flag: int
+ /
+[clinic start generated code]*/
+
+static PyObject *
+sys_mdebug_impl(PyObject *module, int flag)
+/*[clinic end generated code: output=5431d545847c3637 input=151d150ae1636f8a]*/
+{
+ int flag;
+ mallopt(M_DEBUG, flag);
+ Py_RETURN_NONE;
+}
+#endif /* USE_MALLOPT */
+
+size_t
+_PySys_GetSizeOf(PyObject *o)
+{
+ PyObject *res = NULL;
+ PyObject *method;
+ Py_ssize_t size;
+ PyThreadState *tstate = _PyThreadState_GET();
+
+ /* Make sure the type is initialized. float gets initialized late */
+ if (PyType_Ready(Py_TYPE(o)) < 0) {
+ return (size_t)-1;
+ }
+
+ method = _PyObject_LookupSpecial(o, &PyId___sizeof__);
+ if (method == NULL) {
+ if (!_PyErr_Occurred(tstate)) {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "Type %.100s doesn't define __sizeof__",
+ Py_TYPE(o)->tp_name);
+ }
+ }
+ else {
+ res = _PyObject_CallNoArg(method);
+ Py_DECREF(method);
+ }
+
+ if (res == NULL)
+ return (size_t)-1;
+
+ size = PyLong_AsSsize_t(res);
+ Py_DECREF(res);
+ if (size == -1 && _PyErr_Occurred(tstate))
+ return (size_t)-1;
+
+ if (size < 0) {
+ _PyErr_SetString(tstate, PyExc_ValueError,
+ "__sizeof__() should return >= 0");
+ return (size_t)-1;
+ }
+
+ /* add gc_head size */
+ if (_PyObject_IS_GC(o))
+ return ((size_t)size) + sizeof(PyGC_Head);
+ return (size_t)size;
+}
+
+static PyObject *
+sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"object", "default", 0};
+ size_t size;
+ PyObject *o, *dflt = NULL;
+ PyThreadState *tstate = _PyThreadState_GET();
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getsizeof",
+ kwlist, &o, &dflt)) {
+ return NULL;
+ }
+
+ size = _PySys_GetSizeOf(o);
+
+ if (size == (size_t)-1 && _PyErr_Occurred(tstate)) {
+ /* Has a default value been given */
+ if (dflt != NULL && _PyErr_ExceptionMatches(tstate, PyExc_TypeError)) {
+ _PyErr_Clear(tstate);
+ Py_INCREF(dflt);
+ return dflt;
+ }
+ else
+ return NULL;
+ }
+
+ return PyLong_FromSize_t(size);
+}
+
+PyDoc_STRVAR(getsizeof_doc,
+"getsizeof(object [, default]) -> int\n\
+\n\
+Return the size of object in bytes.");
+
+/*[clinic input]
+sys.getrefcount -> Py_ssize_t
+
+ object: object
+ /
+
+Return the reference count of object.
+
+The count returned is generally one higher than you might expect,
+because it includes the (temporary) reference as an argument to
+getrefcount().
+[clinic start generated code]*/
+
+static Py_ssize_t
+sys_getrefcount_impl(PyObject *module, PyObject *object)
+/*[clinic end generated code: output=5fd477f2264b85b2 input=bf474efd50a21535]*/
+{
+ return Py_REFCNT(object);
+}
+
+#ifdef Py_REF_DEBUG
+/*[clinic input]
+sys.gettotalrefcount -> Py_ssize_t
+[clinic start generated code]*/
+
+static Py_ssize_t
+sys_gettotalrefcount_impl(PyObject *module)
+/*[clinic end generated code: output=4103886cf17c25bc input=53b744faa5d2e4f6]*/
+{
+ return _Py_GetRefTotal();
+}
+#endif /* Py_REF_DEBUG */
+
+/*[clinic input]
+sys.getallocatedblocks -> Py_ssize_t
+
+Return the number of memory blocks currently allocated.
+[clinic start generated code]*/
+
+static Py_ssize_t
+sys_getallocatedblocks_impl(PyObject *module)
+/*[clinic end generated code: output=f0c4e873f0b6dcf7 input=dab13ee346a0673e]*/
+{
+ return _Py_GetAllocatedBlocks();
+}
+
+
+/*[clinic input]
+sys._getframe
+
+ depth: int = 0
+ /
+
+Return a frame object from the call stack.
+
+If optional integer depth is given, return the frame object that many
+calls below the top of the stack. If that is deeper than the call
+stack, ValueError is raised. The default for depth is zero, returning
+the frame at the top of the call stack.
+
+This function should be used for internal and specialized purposes
+only.
+[clinic start generated code]*/
+
+static PyObject *
+sys__getframe_impl(PyObject *module, int depth)
+/*[clinic end generated code: output=d438776c04d59804 input=c1be8a6464b11ee5]*/
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyFrameObject *f = PyThreadState_GetFrame(tstate);
+
+ if (_PySys_Audit(tstate, "sys._getframe", "O", f) < 0) {
+ Py_DECREF(f);
+ return NULL;
+ }
+
+ while (depth > 0 && f != NULL) {
+ PyFrameObject *back = PyFrame_GetBack(f);
+ Py_DECREF(f);
+ f = back;
+ --depth;
+ }
+ if (f == NULL) {
+ _PyErr_SetString(tstate, PyExc_ValueError,
+ "call stack is not deep enough");
+ return NULL;
+ }
+ return (PyObject*)f;
+}
+
+/*[clinic input]
+sys._current_frames
+
+Return a dict mapping each thread's thread id to its current stack frame.
+
+This function should be used for specialized purposes only.
+[clinic start generated code]*/
+
+static PyObject *
+sys__current_frames_impl(PyObject *module)
+/*[clinic end generated code: output=d2a41ac0a0a3809a input=2a9049c5f5033691]*/
+{
+ return _PyThread_CurrentFrames();
+}
+
+/*[clinic input]
+sys.call_tracing
+
+ func: object
+ args as funcargs: object(subclass_of='&PyTuple_Type')
+ /
+
+Call func(*args), while tracing is enabled.
+
+The tracing state is saved, and restored afterwards. This is intended
+to be called from a debugger from a checkpoint, to recursively debug
+some other code.
+[clinic start generated code]*/
+
+static PyObject *
+sys_call_tracing_impl(PyObject *module, PyObject *func, PyObject *funcargs)
+/*[clinic end generated code: output=7e4999853cd4e5a6 input=5102e8b11049f92f]*/
+{
+ return _PyEval_CallTracing(func, funcargs);
+}
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*[clinic input]
+sys._debugmallocstats
+
+Print summary info to stderr about the state of pymalloc's structures.
+
+In Py_DEBUG mode, also perform some expensive internal consistency
+checks.
+[clinic start generated code]*/
+
+static PyObject *
+sys__debugmallocstats_impl(PyObject *module)
+/*[clinic end generated code: output=ec3565f8c7cee46a input=33c0c9c416f98424]*/
+{
+#ifdef WITH_PYMALLOC
+ if (_PyObject_DebugMallocStats(stderr)) {
+ fputc('\n', stderr);
+ }
+#endif
+ _PyObject_DebugTypeStats(stderr);
+
+ Py_RETURN_NONE;
+}
+
+#ifdef Py_TRACE_REFS
+/* Defined in objects.c because it uses static globals if that file */
+extern PyObject *_Py_GetObjects(PyObject *, PyObject *);
+#endif
+
+#ifdef DYNAMIC_EXECUTION_PROFILE
+/* Defined in ceval.c because it uses static globals if that file */
+extern PyObject *_Py_GetDXProfile(PyObject *, PyObject *);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/*[clinic input]
+sys._clear_type_cache
+
+Clear the internal type lookup cache.
+[clinic start generated code]*/
+
+static PyObject *
+sys__clear_type_cache_impl(PyObject *module)
+/*[clinic end generated code: output=20e48ca54a6f6971 input=127f3e04a8d9b555]*/
+{
+ PyType_ClearCache();
+ Py_RETURN_NONE;
+}
+
+/*[clinic input]
+sys.is_finalizing
+
+Return True if Python is exiting.
+[clinic start generated code]*/
+
+static PyObject *
+sys_is_finalizing_impl(PyObject *module)
+/*[clinic end generated code: output=735b5ff7962ab281 input=f0df747a039948a5]*/
+{
+ return PyBool_FromLong(_Py_IsFinalizing());
+}
+
+#ifdef ANDROID_API_LEVEL
+/*[clinic input]
+sys.getandroidapilevel
+
+Return the build time API version of Android as an integer.
+[clinic start generated code]*/
+
+static PyObject *
+sys_getandroidapilevel_impl(PyObject *module)
+/*[clinic end generated code: output=214abf183a1c70c1 input=3e6d6c9fcdd24ac6]*/
+{
+ return PyLong_FromLong(ANDROID_API_LEVEL);
+}
+#endif /* ANDROID_API_LEVEL */
+
+
+
+static PyMethodDef sys_methods[] = {
+ /* Might as well keep this in alphabetic order */
+ SYS_ADDAUDITHOOK_METHODDEF
+ {"audit", (PyCFunction)(void(*)(void))sys_audit, METH_FASTCALL, audit_doc },
+ {"breakpointhook", (PyCFunction)(void(*)(void))sys_breakpointhook,
+ METH_FASTCALL | METH_KEYWORDS, breakpointhook_doc},
+ SYS__CLEAR_TYPE_CACHE_METHODDEF
+ SYS__CURRENT_FRAMES_METHODDEF
+ SYS_DISPLAYHOOK_METHODDEF
+ SYS_EXC_INFO_METHODDEF
+ SYS_EXCEPTHOOK_METHODDEF
+ SYS_EXIT_METHODDEF
+ SYS_GETDEFAULTENCODING_METHODDEF
+ SYS_GETDLOPENFLAGS_METHODDEF
+ SYS_GETALLOCATEDBLOCKS_METHODDEF
+#ifdef DYNAMIC_EXECUTION_PROFILE
+ {"getdxp", _Py_GetDXProfile, METH_VARARGS},
+#endif
+ SYS_GETFILESYSTEMENCODING_METHODDEF
+ SYS_GETFILESYSTEMENCODEERRORS_METHODDEF
+#ifdef Py_TRACE_REFS
+ {"getobjects", _Py_GetObjects, METH_VARARGS},
+#endif
+ SYS_GETTOTALREFCOUNT_METHODDEF
+ SYS_GETREFCOUNT_METHODDEF
+ SYS_GETRECURSIONLIMIT_METHODDEF
+ {"getsizeof", (PyCFunction)(void(*)(void))sys_getsizeof,
+ METH_VARARGS | METH_KEYWORDS, getsizeof_doc},
+ SYS__GETFRAME_METHODDEF
+ SYS_GETWINDOWSVERSION_METHODDEF
+ SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF
+ SYS_INTERN_METHODDEF
+ SYS_IS_FINALIZING_METHODDEF
+ SYS_MDEBUG_METHODDEF
+ SYS_SETSWITCHINTERVAL_METHODDEF
+ SYS_GETSWITCHINTERVAL_METHODDEF
+ SYS_SETDLOPENFLAGS_METHODDEF
+ {"setprofile", sys_setprofile, METH_O, setprofile_doc},
+ SYS_GETPROFILE_METHODDEF
+ SYS_SETRECURSIONLIMIT_METHODDEF
+ {"settrace", sys_settrace, METH_O, settrace_doc},
+ SYS_GETTRACE_METHODDEF
+ SYS_CALL_TRACING_METHODDEF
+ SYS__DEBUGMALLOCSTATS_METHODDEF
+ SYS_SET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF
+ SYS_GET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF
+ {"set_asyncgen_hooks", (PyCFunction)(void(*)(void))sys_set_asyncgen_hooks,
+ METH_VARARGS | METH_KEYWORDS, set_asyncgen_hooks_doc},
+ SYS_GET_ASYNCGEN_HOOKS_METHODDEF
+ SYS_GETANDROIDAPILEVEL_METHODDEF
+ SYS_UNRAISABLEHOOK_METHODDEF
+ {NULL, NULL} /* sentinel */
+};
+
+static PyObject *
+list_builtin_module_names(void)
+{
+ PyObject *list = PyList_New(0);
+ int i;
+ if (list == NULL)
+ return NULL;
+ for (i = 0; PyImport_Inittab[i].name != NULL; i++) {
+ PyObject *name = PyUnicode_FromString(
+ PyImport_Inittab[i].name);
+ if (name == NULL)
+ break;
+ PyList_Append(list, name);
+ Py_DECREF(name);
+ }
+ if (PyList_Sort(list) != 0) {
+ Py_DECREF(list);
+ list = NULL;
+ }
+ if (list) {
+ PyObject *v = PyList_AsTuple(list);
+ Py_DECREF(list);
+ list = v;
+ }
+ return list;
+}
+
+/* Pre-initialization support for sys.warnoptions and sys._xoptions
+ *
+ * Modern internal code paths:
+ * These APIs get called after _Py_InitializeCore and get to use the
+ * regular CPython list, dict, and unicode APIs.
+ *
+ * Legacy embedding code paths:
+ * The multi-phase initialization API isn't public yet, so embedding
+ * apps still need to be able configure sys.warnoptions and sys._xoptions
+ * before they call Py_Initialize. To support this, we stash copies of
+ * the supplied wchar * sequences in linked lists, and then migrate the
+ * contents of those lists to the sys module in _PyInitializeCore.
+ *
+ */
+
+struct _preinit_entry {
+ wchar_t *value;
+ struct _preinit_entry *next;
+};
+
+typedef struct _preinit_entry *_Py_PreInitEntry;
+
+static _Py_PreInitEntry _preinit_warnoptions = NULL;
+static _Py_PreInitEntry _preinit_xoptions = NULL;
+
+static _Py_PreInitEntry
+_alloc_preinit_entry(const wchar_t *value)
+{
+ /* To get this to work, we have to initialize the runtime implicitly */
+ _PyRuntime_Initialize();
+
+ /* Force default allocator, so we can ensure that it also gets used to
+ * destroy the linked list in _clear_preinit_entries.
+ */
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ _Py_PreInitEntry node = PyMem_RawCalloc(1, sizeof(*node));
+ if (node != NULL) {
+ node->value = _PyMem_RawWcsdup(value);
+ if (node->value == NULL) {
+ PyMem_RawFree(node);
+ node = NULL;
+ };
+ };
+
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+ return node;
+}
+
+static int
+_append_preinit_entry(_Py_PreInitEntry *optionlist, const wchar_t *value)
+{
+ _Py_PreInitEntry new_entry = _alloc_preinit_entry(value);
+ if (new_entry == NULL) {
+ return -1;
+ }
+ /* We maintain the linked list in this order so it's easy to play back
+ * the add commands in the same order later on in _Py_InitializeCore
+ */
+ _Py_PreInitEntry last_entry = *optionlist;
+ if (last_entry == NULL) {
+ *optionlist = new_entry;
+ } else {
+ while (last_entry->next != NULL) {
+ last_entry = last_entry->next;
+ }
+ last_entry->next = new_entry;
+ }
+ return 0;
+}
+
+static void
+_clear_preinit_entries(_Py_PreInitEntry *optionlist)
+{
+ _Py_PreInitEntry current = *optionlist;
+ *optionlist = NULL;
+ /* Deallocate the nodes and their contents using the default allocator */
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+ while (current != NULL) {
+ _Py_PreInitEntry next = current->next;
+ PyMem_RawFree(current->value);
+ PyMem_RawFree(current);
+ current = next;
+ }
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+}
+
+
+PyStatus
+_PySys_ReadPreinitWarnOptions(PyWideStringList *options)
+{
+ PyStatus status;
+ _Py_PreInitEntry entry;
+
+ for (entry = _preinit_warnoptions; entry != NULL; entry = entry->next) {
+ status = PyWideStringList_Append(options, entry->value);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ _clear_preinit_entries(&_preinit_warnoptions);
+ return _PyStatus_OK();
+}
+
+
+PyStatus
+_PySys_ReadPreinitXOptions(PyConfig *config)
+{
+ PyStatus status;
+ _Py_PreInitEntry entry;
+
+ for (entry = _preinit_xoptions; entry != NULL; entry = entry->next) {
+ status = PyWideStringList_Append(&config->xoptions, entry->value);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
+ _clear_preinit_entries(&_preinit_xoptions);
+ return _PyStatus_OK();
+}
+
+
+static PyObject *
+get_warnoptions(PyThreadState *tstate)
+{
+ PyObject *warnoptions = sys_get_object_id(tstate, &PyId_warnoptions);
+ if (warnoptions == NULL || !PyList_Check(warnoptions)) {
+ /* PEP432 TODO: we can reach this if warnoptions is NULL in the main
+ * interpreter config. When that happens, we need to properly set
+ * the `warnoptions` reference in the main interpreter config as well.
+ *
+ * For Python 3.7, we shouldn't be able to get here due to the
+ * combination of how _PyMainInterpreter_ReadConfig and _PySys_EndInit
+ * work, but we expect 3.8+ to make the _PyMainInterpreter_ReadConfig
+ * call optional for embedding applications, thus making this
+ * reachable again.
+ */
+ warnoptions = PyList_New(0);
+ if (warnoptions == NULL) {
+ return NULL;
+ }
+ if (sys_set_object_id(tstate, &PyId_warnoptions, warnoptions)) {
+ Py_DECREF(warnoptions);
+ return NULL;
+ }
+ Py_DECREF(warnoptions);
+ }
+ return warnoptions;
+}
+
+void
+PySys_ResetWarnOptions(void)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (tstate == NULL) {
+ _clear_preinit_entries(&_preinit_warnoptions);
+ return;
+ }
+
+ PyObject *warnoptions = sys_get_object_id(tstate, &PyId_warnoptions);
+ if (warnoptions == NULL || !PyList_Check(warnoptions))
+ return;
+ PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL);
+}
+
+static int
+_PySys_AddWarnOptionWithError(PyThreadState *tstate, PyObject *option)
+{
+ PyObject *warnoptions = get_warnoptions(tstate);
+ if (warnoptions == NULL) {
+ return -1;
+ }
+ if (PyList_Append(warnoptions, option)) {
+ return -1;
+ }
+ return 0;
+}
+
+void
+PySys_AddWarnOptionUnicode(PyObject *option)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (_PySys_AddWarnOptionWithError(tstate, option) < 0) {
+ /* No return value, therefore clear error state if possible */
+ if (tstate) {
+ _PyErr_Clear(tstate);
+ }
+ }
+}
+
+void
+PySys_AddWarnOption(const wchar_t *s)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (tstate == NULL) {
+ _append_preinit_entry(&_preinit_warnoptions, s);
+ return;
+ }
+ PyObject *unicode;
+ unicode = PyUnicode_FromWideChar(s, -1);
+ if (unicode == NULL)
+ return;
+ PySys_AddWarnOptionUnicode(unicode);
+ Py_DECREF(unicode);
+}
+
+int
+PySys_HasWarnOptions(void)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyObject *warnoptions = sys_get_object_id(tstate, &PyId_warnoptions);
+ return (warnoptions != NULL && PyList_Check(warnoptions)
+ && PyList_GET_SIZE(warnoptions) > 0);
+}
+
+static PyObject *
+get_xoptions(PyThreadState *tstate)
+{
+ PyObject *xoptions = sys_get_object_id(tstate, &PyId__xoptions);
+ if (xoptions == NULL || !PyDict_Check(xoptions)) {
+ /* PEP432 TODO: we can reach this if xoptions is NULL in the main
+ * interpreter config. When that happens, we need to properly set
+ * the `xoptions` reference in the main interpreter config as well.
+ *
+ * For Python 3.7, we shouldn't be able to get here due to the
+ * combination of how _PyMainInterpreter_ReadConfig and _PySys_EndInit
+ * work, but we expect 3.8+ to make the _PyMainInterpreter_ReadConfig
+ * call optional for embedding applications, thus making this
+ * reachable again.
+ */
+ xoptions = PyDict_New();
+ if (xoptions == NULL) {
+ return NULL;
+ }
+ if (sys_set_object_id(tstate, &PyId__xoptions, xoptions)) {
+ Py_DECREF(xoptions);
+ return NULL;
+ }
+ Py_DECREF(xoptions);
+ }
+ return xoptions;
+}
+
+static int
+_PySys_AddXOptionWithError(const wchar_t *s)
+{
+ PyObject *name = NULL, *value = NULL;
+
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyObject *opts = get_xoptions(tstate);
+ if (opts == NULL) {
+ goto error;
+ }
+
+ const wchar_t *name_end = wcschr(s, L'=');
+ if (!name_end) {
+ name = PyUnicode_FromWideChar(s, -1);
+ value = Py_True;
+ Py_INCREF(value);
+ }
+ else {
+ name = PyUnicode_FromWideChar(s, name_end - s);
+ value = PyUnicode_FromWideChar(name_end + 1, -1);
+ }
+ if (name == NULL || value == NULL) {
+ goto error;
+ }
+ if (PyDict_SetItem(opts, name, value) < 0) {
+ goto error;
+ }
+ Py_DECREF(name);
+ Py_DECREF(value);
+ return 0;
+
+error:
+ Py_XDECREF(name);
+ Py_XDECREF(value);
+ return -1;
+}
+
+void
+PySys_AddXOption(const wchar_t *s)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (tstate == NULL) {
+ _append_preinit_entry(&_preinit_xoptions, s);
+ return;
+ }
+ if (_PySys_AddXOptionWithError(s) < 0) {
+ /* No return value, therefore clear error state if possible */
+ _PyErr_Clear(tstate);
+ }
+}
+
+PyObject *
+PySys_GetXOptions(void)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ return get_xoptions(tstate);
+}
+
+/* XXX This doc string is too long to be a single string literal in VC++ 5.0.
+ Two literals concatenated works just fine. If you have a K&R compiler
+ or other abomination that however *does* understand longer strings,
+ get rid of the !!! comment in the middle and the quotes that surround it. */
+PyDoc_VAR(sys_doc) =
+PyDoc_STR(
+"This module provides access to some objects used or maintained by the\n\
+interpreter and to functions that interact strongly with the interpreter.\n\
+\n\
+Dynamic objects:\n\
+\n\
+argv -- command line arguments; argv[0] is the script pathname if known\n\
+path -- module search path; path[0] is the script directory, else ''\n\
+modules -- dictionary of loaded modules\n\
+\n\
+displayhook -- called to show results in an interactive session\n\
+excepthook -- called to handle any uncaught exception other than SystemExit\n\
+ To customize printing in an interactive session or to install a custom\n\
+ top-level exception handler, assign other functions to replace these.\n\
+\n\
+stdin -- standard input file object; used by input()\n\
+stdout -- standard output file object; used by print()\n\
+stderr -- standard error object; used for error messages\n\
+ By assigning other file objects (or objects that behave like files)\n\
+ to these, it is possible to redirect all of the interpreter's I/O.\n\
+\n\
+last_type -- type of last uncaught exception\n\
+last_value -- value of last uncaught exception\n\
+last_traceback -- traceback of last uncaught exception\n\
+ These three are only available in an interactive session after a\n\
+ traceback has been printed.\n\
+"
+)
+/* concatenating string here */
+PyDoc_STR(
+"\n\
+Static objects:\n\
+\n\
+builtin_module_names -- tuple of module names built into this interpreter\n\
+copyright -- copyright notice pertaining to this interpreter\n\
+exec_prefix -- prefix used to find the machine-specific Python library\n\
+executable -- absolute path of the executable binary of the Python interpreter\n\
+float_info -- a named tuple with information about the float implementation.\n\
+float_repr_style -- string indicating the style of repr() output for floats\n\
+hash_info -- a named tuple with information about the hash algorithm.\n\
+hexversion -- version information encoded as a single integer\n\
+implementation -- Python implementation information.\n\
+int_info -- a named tuple with information about the int implementation.\n\
+maxsize -- the largest supported length of containers.\n\
+maxunicode -- the value of the largest Unicode code point\n\
+platform -- platform identifier\n\
+prefix -- prefix used to find the Python library\n\
+thread_info -- a named tuple with information about the thread implementation.\n\
+version -- the version of this interpreter as a string\n\
+version_info -- version information as a named tuple\n\
+"
+)
+#ifdef MS_COREDLL
+/* concatenating string here */
+PyDoc_STR(
+"dllhandle -- [Windows only] integer handle of the Python DLL\n\
+winver -- [Windows only] version number of the Python DLL\n\
+"
+)
+#endif /* MS_COREDLL */
+#ifdef MS_WINDOWS
+/* concatenating string here */
+PyDoc_STR(
+"_enablelegacywindowsfsencoding -- [Windows only]\n\
+"
+)
+#endif
+PyDoc_STR(
+"__stdin__ -- the original stdin; don't touch!\n\
+__stdout__ -- the original stdout; don't touch!\n\
+__stderr__ -- the original stderr; don't touch!\n\
+__displayhook__ -- the original displayhook; don't touch!\n\
+__excepthook__ -- the original excepthook; don't touch!\n\
+\n\
+Functions:\n\
+\n\
+displayhook() -- print an object to the screen, and save it in builtins._\n\
+excepthook() -- print an exception and its traceback to sys.stderr\n\
+exc_info() -- return thread-safe information about the current exception\n\
+exit() -- exit the interpreter by raising SystemExit\n\
+getdlopenflags() -- returns flags to be used for dlopen() calls\n\
+getprofile() -- get the global profiling function\n\
+getrefcount() -- return the reference count for an object (plus one :-)\n\
+getrecursionlimit() -- return the max recursion depth for the interpreter\n\
+getsizeof() -- return the size of an object in bytes\n\
+gettrace() -- get the global debug tracing function\n\
+setdlopenflags() -- set the flags to be used for dlopen() calls\n\
+setprofile() -- set the global profiling function\n\
+setrecursionlimit() -- set the max recursion depth for the interpreter\n\
+settrace() -- set the global debug tracing function\n\
+"
+)
+/* end of sys_doc */ ;
+
+
+PyDoc_STRVAR(flags__doc__,
+"sys.flags\n\
+\n\
+Flags provided through command line arguments or environment vars.");
+
+static PyTypeObject FlagsType;
+
+static PyStructSequence_Field flags_fields[] = {
+ {"debug", "-d"},
+ {"inspect", "-i"},
+ {"interactive", "-i"},
+ {"optimize", "-O or -OO"},
+ {"dont_write_bytecode", "-B"},
+ {"no_user_site", "-s"},
+ {"no_site", "-S"},
+ {"ignore_environment", "-E"},
+ {"verbose", "-v"},
+ /* {"unbuffered", "-u"}, */
+ /* {"skip_first", "-x"}, */
+ {"bytes_warning", "-b"},
+ {"quiet", "-q"},
+ {"hash_randomization", "-R"},
+ {"isolated", "-I"},
+ {"dev_mode", "-X dev"},
+ {"utf8_mode", "-X utf8"},
+ {0}
+};
+
+static PyStructSequence_Desc flags_desc = {
+ "sys.flags", /* name */
+ flags__doc__, /* doc */
+ flags_fields, /* fields */
+ 15
+};
+
+static PyObject*
+make_flags(PyThreadState *tstate)
+{
+ PyInterpreterState *interp = tstate->interp;
+ const PyPreConfig *preconfig = &interp->runtime->preconfig;
+ const PyConfig *config = _PyInterpreterState_GetConfig(interp);
+
+ PyObject *seq = PyStructSequence_New(&FlagsType);
+ if (seq == NULL) {
+ return NULL;
+ }
+
+ int pos = 0;
+#define SetFlag(flag) \
+ PyStructSequence_SET_ITEM(seq, pos++, PyLong_FromLong(flag))
+
+ SetFlag(config->parser_debug);
+ SetFlag(config->inspect);
+ SetFlag(config->interactive);
+ SetFlag(config->optimization_level);
+ SetFlag(!config->write_bytecode);
+ SetFlag(!config->user_site_directory);
+ SetFlag(!config->site_import);
+ SetFlag(!config->use_environment);
+ SetFlag(config->verbose);
+ /* SetFlag(saw_unbuffered_flag); */
+ /* SetFlag(skipfirstline); */
+ SetFlag(config->bytes_warning);
+ SetFlag(config->quiet);
+ SetFlag(config->use_hash_seed == 0 || config->hash_seed != 0);
+ SetFlag(config->isolated);
+ PyStructSequence_SET_ITEM(seq, pos++, PyBool_FromLong(config->dev_mode));
+ SetFlag(preconfig->utf8_mode);
+#undef SetFlag
+
+ if (_PyErr_Occurred(tstate)) {
+ Py_DECREF(seq);
+ return NULL;
+ }
+ return seq;
+}
+
+PyDoc_STRVAR(version_info__doc__,
+"sys.version_info\n\
+\n\
+Version information as a named tuple.");
+
+static PyTypeObject VersionInfoType;
+
+static PyStructSequence_Field version_info_fields[] = {
+ {"major", "Major release number"},
+ {"minor", "Minor release number"},
+ {"micro", "Patch release number"},
+ {"releaselevel", "'alpha', 'beta', 'candidate', or 'final'"},
+ {"serial", "Serial release number"},
+ {0}
+};
+
+static PyStructSequence_Desc version_info_desc = {
+ "sys.version_info", /* name */
+ version_info__doc__, /* doc */
+ version_info_fields, /* fields */
+ 5
+};
+
+static PyObject *
+make_version_info(PyThreadState *tstate)
+{
+ PyObject *version_info;
+ char *s;
+ int pos = 0;
+
+ version_info = PyStructSequence_New(&VersionInfoType);
+ if (version_info == NULL) {
+ return NULL;
+ }
+
+ /*
+ * These release level checks are mutually exclusive and cover
+ * the field, so don't get too fancy with the pre-processor!
+ */
+#if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA
+ s = "alpha";
+#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA
+ s = "beta";
+#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA
+ s = "candidate";
+#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL
+ s = "final";
+#endif
+
+#define SetIntItem(flag) \
+ PyStructSequence_SET_ITEM(version_info, pos++, PyLong_FromLong(flag))
+#define SetStrItem(flag) \
+ PyStructSequence_SET_ITEM(version_info, pos++, PyUnicode_FromString(flag))
+
+ SetIntItem(PY_MAJOR_VERSION);
+ SetIntItem(PY_MINOR_VERSION);
+ SetIntItem(PY_MICRO_VERSION);
+ SetStrItem(s);
+ SetIntItem(PY_RELEASE_SERIAL);
+#undef SetIntItem
+#undef SetStrItem
+
+ if (_PyErr_Occurred(tstate)) {
+ Py_CLEAR(version_info);
+ return NULL;
+ }
+ return version_info;
+}
+
+/* sys.implementation values */
+#define NAME "cpython"
+const char *_PySys_ImplName = NAME;
+#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
+#undef MAJOR
+#undef MINOR
+#undef TAG
+
+static PyObject *
+make_impl_info(PyObject *version_info)
+{
+ int res;
+ PyObject *impl_info, *value, *ns;
+
+ impl_info = PyDict_New();
+ if (impl_info == NULL)
+ return NULL;
+
+ /* populate the dict */
+
+ value = PyUnicode_FromString(_PySys_ImplName);
+ if (value == NULL)
+ goto error;
+ res = PyDict_SetItemString(impl_info, "name", value);
+ Py_DECREF(value);
+ if (res < 0)
+ goto error;
+
+ value = PyUnicode_FromString(_PySys_ImplCacheTag);
+ if (value == NULL)
+ goto error;
+ res = PyDict_SetItemString(impl_info, "cache_tag", value);
+ Py_DECREF(value);
+ if (res < 0)
+ goto error;
+
+ res = PyDict_SetItemString(impl_info, "version", version_info);
+ if (res < 0)
+ goto error;
+
+ value = PyLong_FromLong(PY_VERSION_HEX);
+ if (value == NULL)
+ goto error;
+ res = PyDict_SetItemString(impl_info, "hexversion", value);
+ Py_DECREF(value);
+ if (res < 0)
+ goto error;
+
+#ifdef MULTIARCH
+ value = PyUnicode_FromString(MULTIARCH);
+ if (value == NULL)
+ goto error;
+ res = PyDict_SetItemString(impl_info, "_multiarch", value);
+ Py_DECREF(value);
+ if (res < 0)
+ goto error;
+#endif
+
+ /* dict ready */
+
+ ns = _PyNamespace_New(impl_info);
+ Py_DECREF(impl_info);
+ return ns;
+
+error:
+ Py_CLEAR(impl_info);
+ return NULL;
+}
+
+static struct PyModuleDef sysmodule = {
+ PyModuleDef_HEAD_INIT,
+ "sys",
+ sys_doc,
+ -1, /* multiple "initialization" just copies the module dict. */
+ sys_methods,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+/* Updating the sys namespace, returning NULL pointer on error */
+#define SET_SYS_FROM_STRING_BORROW(key, value) \
+ do { \
+ PyObject *v = (value); \
+ if (v == NULL) { \
+ goto err_occurred; \
+ } \
+ res = PyDict_SetItemString(sysdict, key, v); \
+ if (res < 0) { \
+ goto err_occurred; \
+ } \
+ } while (0)
+#define SET_SYS_FROM_STRING(key, value) \
+ do { \
+ PyObject *v = (value); \
+ if (v == NULL) { \
+ goto err_occurred; \
+ } \
+ res = PyDict_SetItemString(sysdict, key, v); \
+ Py_DECREF(v); \
+ if (res < 0) { \
+ goto err_occurred; \
+ } \
+ } while (0)
+
+static PyStatus
+_PySys_InitCore(PyThreadState *tstate, PyObject *sysdict)
+{
+ PyObject *version_info;
+ int res;
+
+ /* stdin/stdout/stderr are set in pylifecycle.c */
+
+ SET_SYS_FROM_STRING_BORROW("__displayhook__",
+ PyDict_GetItemString(sysdict, "displayhook"));
+ SET_SYS_FROM_STRING_BORROW("__excepthook__",
+ PyDict_GetItemString(sysdict, "excepthook"));
+ SET_SYS_FROM_STRING_BORROW(
+ "__breakpointhook__",
+ PyDict_GetItemString(sysdict, "breakpointhook"));
+ SET_SYS_FROM_STRING_BORROW("__unraisablehook__",
+ PyDict_GetItemString(sysdict, "unraisablehook"));
+
+ SET_SYS_FROM_STRING("version",
+ PyUnicode_FromString(Py_GetVersion()));
+ SET_SYS_FROM_STRING("hexversion",
+ PyLong_FromLong(PY_VERSION_HEX));
+ SET_SYS_FROM_STRING("_git",
+ Py_BuildValue("(szz)", "CPython", _Py_gitidentifier(),
+ _Py_gitversion()));
+ SET_SYS_FROM_STRING("_framework", PyUnicode_FromString(_PYTHONFRAMEWORK));
+ SET_SYS_FROM_STRING("api_version",
+ PyLong_FromLong(PYTHON_API_VERSION));
+ SET_SYS_FROM_STRING("copyright",
+ PyUnicode_FromString(Py_GetCopyright()));
+ SET_SYS_FROM_STRING("platform",
+ PyUnicode_FromString(Py_GetPlatform()));
+ SET_SYS_FROM_STRING("maxsize",
+ PyLong_FromSsize_t(PY_SSIZE_T_MAX));
+ SET_SYS_FROM_STRING("float_info",
+ PyFloat_GetInfo());
+ SET_SYS_FROM_STRING("int_info",
+ PyLong_GetInfo());
+ /* initialize hash_info */
+ if (Hash_InfoType.tp_name == NULL) {
+ if (PyStructSequence_InitType2(&Hash_InfoType, &hash_info_desc) < 0) {
+ goto type_init_failed;
+ }
+ }
+ SET_SYS_FROM_STRING("hash_info",
+ get_hash_info(tstate));
+ SET_SYS_FROM_STRING("maxunicode",
+ PyLong_FromLong(0x10FFFF));
+ SET_SYS_FROM_STRING("builtin_module_names",
+ list_builtin_module_names());
+#if PY_BIG_ENDIAN
+ SET_SYS_FROM_STRING("byteorder",
+ PyUnicode_FromString("big"));
+#else
+ SET_SYS_FROM_STRING("byteorder",
+ PyUnicode_FromString("little"));
+#endif
+
+#ifdef MS_COREDLL
+ SET_SYS_FROM_STRING("dllhandle",
+ PyLong_FromVoidPtr(PyWin_DLLhModule));
+ SET_SYS_FROM_STRING("winver",
+ PyUnicode_FromString(PyWin_DLLVersionString));
+#endif
+#ifdef ABIFLAGS
+ SET_SYS_FROM_STRING("abiflags",
+ PyUnicode_FromString(ABIFLAGS));
+#endif
+
+ /* version_info */
+ if (VersionInfoType.tp_name == NULL) {
+ if (PyStructSequence_InitType2(&VersionInfoType,
+ &version_info_desc) < 0) {
+ goto type_init_failed;
+ }
+ }
+ version_info = make_version_info(tstate);
+ SET_SYS_FROM_STRING("version_info", version_info);
+ /* prevent user from creating new instances */
+ VersionInfoType.tp_init = NULL;
+ VersionInfoType.tp_new = NULL;
+ res = PyDict_DelItemString(VersionInfoType.tp_dict, "__new__");
+ if (res < 0 && _PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
+ _PyErr_Clear(tstate);
+ }
+
+ /* implementation */
+ SET_SYS_FROM_STRING("implementation", make_impl_info(version_info));
+
+ /* flags */
+ if (FlagsType.tp_name == 0) {
+ if (PyStructSequence_InitType2(&FlagsType, &flags_desc) < 0) {
+ goto type_init_failed;
+ }
+ }
+ /* Set flags to their default values (updated by _PySys_InitMain()) */
+ SET_SYS_FROM_STRING("flags", make_flags(tstate));
+
+#if defined(MS_WINDOWS)
+ /* getwindowsversion */
+ if (WindowsVersionType.tp_name == 0)
+ if (PyStructSequence_InitType2(&WindowsVersionType,
+ &windows_version_desc) < 0) {
+ goto type_init_failed;
+ }
+ /* prevent user from creating new instances */
+ WindowsVersionType.tp_init = NULL;
+ WindowsVersionType.tp_new = NULL;
+ assert(!_PyErr_Occurred(tstate));
+ res = PyDict_DelItemString(WindowsVersionType.tp_dict, "__new__");
+ if (res < 0 && _PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
+ _PyErr_Clear(tstate);
+ }
+#endif
+
+ /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */
+#ifndef PY_NO_SHORT_FLOAT_REPR
+ SET_SYS_FROM_STRING("float_repr_style",
+ PyUnicode_FromString("short"));
+#else
+ SET_SYS_FROM_STRING("float_repr_style",
+ PyUnicode_FromString("legacy"));
+#endif
+
+ SET_SYS_FROM_STRING("thread_info", PyThread_GetInfo());
+
+ /* initialize asyncgen_hooks */
+ if (AsyncGenHooksType.tp_name == NULL) {
+ if (PyStructSequence_InitType2(
+ &AsyncGenHooksType, &asyncgen_hooks_desc) < 0) {
+ goto type_init_failed;
+ }
+ }
+
+ if (_PyErr_Occurred(tstate)) {
+ goto err_occurred;
+ }
+ return _PyStatus_OK();
+
+type_init_failed:
+ return _PyStatus_ERR("failed to initialize a type");
+
+err_occurred:
+ return _PyStatus_ERR("can't initialize sys module");
+}
+
+/* Updating the sys namespace, returning integer error codes */
+#define SET_SYS_FROM_STRING_INT_RESULT(key, value) \
+ do { \
+ PyObject *v = (value); \
+ if (v == NULL) \
+ return -1; \
+ res = PyDict_SetItemString(sysdict, key, v); \
+ Py_DECREF(v); \
+ if (res < 0) { \
+ return res; \
+ } \
+ } while (0)
+
+
+static int
+sys_add_xoption(PyObject *opts, const wchar_t *s)
+{
+ PyObject *name, *value;
+
+ const wchar_t *name_end = wcschr(s, L'=');
+ if (!name_end) {
+ name = PyUnicode_FromWideChar(s, -1);
+ value = Py_True;
+ Py_INCREF(value);
+ }
+ else {
+ name = PyUnicode_FromWideChar(s, name_end - s);
+ value = PyUnicode_FromWideChar(name_end + 1, -1);
+ }
+ if (name == NULL || value == NULL) {
+ goto error;
+ }
+ if (PyDict_SetItem(opts, name, value) < 0) {
+ goto error;
+ }
+ Py_DECREF(name);
+ Py_DECREF(value);
+ return 0;
+
+error:
+ Py_XDECREF(name);
+ Py_XDECREF(value);
+ return -1;
+}
+
+
+static PyObject*
+sys_create_xoptions_dict(const PyConfig *config)
+{
+ Py_ssize_t nxoption = config->xoptions.length;
+ wchar_t * const * xoptions = config->xoptions.items;
+ PyObject *dict = PyDict_New();
+ if (dict == NULL) {
+ return NULL;
+ }
+
+ for (Py_ssize_t i=0; i < nxoption; i++) {
+ const wchar_t *option = xoptions[i];
+ if (sys_add_xoption(dict, option) < 0) {
+ Py_DECREF(dict);
+ return NULL;
+ }
+ }
+
+ return dict;
+}
+
+
+int
+_PySys_InitMain(PyThreadState *tstate)
+{
+ PyObject *sysdict = tstate->interp->sysdict;
+ const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
+ int res;
+
+#define COPY_LIST(KEY, VALUE) \
+ do { \
+ PyObject *list = _PyWideStringList_AsList(&(VALUE)); \
+ if (list == NULL) { \
+ return -1; \
+ } \
+ SET_SYS_FROM_STRING_BORROW(KEY, list); \
+ Py_DECREF(list); \
+ } while (0)
+
+#define SET_SYS_FROM_WSTR(KEY, VALUE) \
+ do { \
+ PyObject *str = PyUnicode_FromWideChar(VALUE, -1); \
+ if (str == NULL) { \
+ return -1; \
+ } \
+ SET_SYS_FROM_STRING_BORROW(KEY, str); \
+ Py_DECREF(str); \
+ } while (0)
+
+ COPY_LIST("path", config->module_search_paths);
+
+ SET_SYS_FROM_WSTR("executable", config->executable);
+ SET_SYS_FROM_WSTR("_base_executable", config->base_executable);
+ SET_SYS_FROM_WSTR("prefix", config->prefix);
+ SET_SYS_FROM_WSTR("base_prefix", config->base_prefix);
+ SET_SYS_FROM_WSTR("exec_prefix", config->exec_prefix);
+ SET_SYS_FROM_WSTR("base_exec_prefix", config->base_exec_prefix);
+ SET_SYS_FROM_WSTR("platlibdir", config->platlibdir);
+
+ if (config->pycache_prefix != NULL) {
+ SET_SYS_FROM_WSTR("pycache_prefix", config->pycache_prefix);
+ } else {
+ PyDict_SetItemString(sysdict, "pycache_prefix", Py_None);
+ }
+
+ COPY_LIST("argv", config->argv);
+ COPY_LIST("warnoptions", config->warnoptions);
+
+ PyObject *xoptions = sys_create_xoptions_dict(config);
+ if (xoptions == NULL) {
+ return -1;
+ }
+ SET_SYS_FROM_STRING_BORROW("_xoptions", xoptions);
+ Py_DECREF(xoptions);
+
+#undef COPY_LIST
+#undef SET_SYS_FROM_WSTR
+
+
+ /* Set flags to their final values */
+ SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags(tstate));
+ /* prevent user from creating new instances */
+ FlagsType.tp_init = NULL;
+ FlagsType.tp_new = NULL;
+ res = PyDict_DelItemString(FlagsType.tp_dict, "__new__");
+ if (res < 0) {
+ if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
+ return res;
+ }
+ _PyErr_Clear(tstate);
+ }
+
+ SET_SYS_FROM_STRING_INT_RESULT("dont_write_bytecode",
+ PyBool_FromLong(!config->write_bytecode));
+
+ if (get_warnoptions(tstate) == NULL) {
+ return -1;
+ }
+
+ if (get_xoptions(tstate) == NULL)
+ return -1;
+
+ if (_PyErr_Occurred(tstate)) {
+ goto err_occurred;
+ }
+
+ return 0;
+
+err_occurred:
+ return -1;
+}
+
+#undef SET_SYS_FROM_STRING
+#undef SET_SYS_FROM_STRING_BORROW
+#undef SET_SYS_FROM_STRING_INT_RESULT
+
+
+/* Set up a preliminary stderr printer until we have enough
+ infrastructure for the io module in place.
+
+ Use UTF-8/surrogateescape and ignore EAGAIN errors. */
+static PyStatus
+_PySys_SetPreliminaryStderr(PyObject *sysdict)
+{
+ PyObject *pstderr = PyFile_NewStdPrinter(fileno(stderr));
+ if (pstderr == NULL) {
+ goto error;
+ }
+ if (_PyDict_SetItemId(sysdict, &PyId_stderr, pstderr) < 0) {
+ goto error;
+ }
+ if (PyDict_SetItemString(sysdict, "__stderr__", pstderr) < 0) {
+ goto error;
+ }
+ Py_DECREF(pstderr);
+ return _PyStatus_OK();
+
+error:
+ Py_XDECREF(pstderr);
+ return _PyStatus_ERR("can't set preliminary stderr");
+}
+
+
+/* Create sys module without all attributes: _PySys_InitMain() should be called
+ later to add remaining attributes. */
+PyStatus
+_PySys_Create(PyThreadState *tstate, PyObject **sysmod_p)
+{
+ assert(!_PyErr_Occurred(tstate));
+
+ PyInterpreterState *interp = tstate->interp;
+
+ PyObject *modules = PyDict_New();
+ if (modules == NULL) {
+ goto error;
+ }
+ interp->modules = modules;
+
+ PyObject *sysmod = _PyModule_CreateInitialized(&sysmodule, PYTHON_API_VERSION);
+ if (sysmod == NULL) {
+ return _PyStatus_ERR("failed to create a module object");
+ }
+
+ PyObject *sysdict = PyModule_GetDict(sysmod);
+ if (sysdict == NULL) {
+ goto error;
+ }
+ Py_INCREF(sysdict);
+ interp->sysdict = sysdict;
+
+ if (PyDict_SetItemString(sysdict, "modules", interp->modules) < 0) {
+ goto error;
+ }
+
+ PyStatus status = _PySys_SetPreliminaryStderr(sysdict);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ status = _PySys_InitCore(tstate, sysdict);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ if (_PyImport_FixupBuiltin(sysmod, "sys", interp->modules) < 0) {
+ goto error;
+ }
+
+ assert(!_PyErr_Occurred(tstate));
+
+ *sysmod_p = sysmod;
+ return _PyStatus_OK();
+
+error:
+ return _PyStatus_ERR("can't initialize sys module");
+}
+
+
+static PyObject *
+makepathobject(const wchar_t *path, wchar_t delim)
+{
+ int i, n;
+ const wchar_t *p;
+ PyObject *v, *w;
+
+ n = 1;
+ p = path;
+ while ((p = wcschr(p, delim)) != NULL) {
+ n++;
+ p++;
+ }
+ v = PyList_New(n);
+ if (v == NULL)
+ return NULL;
+ for (i = 0; ; i++) {
+ p = wcschr(path, delim);
+ if (p == NULL)
+ p = path + wcslen(path); /* End of string */
+ w = PyUnicode_FromWideChar(path, (Py_ssize_t)(p - path));
+ if (w == NULL) {
+ Py_DECREF(v);
+ return NULL;
+ }
+ PyList_SET_ITEM(v, i, w);
+ if (*p == '\0')
+ break;
+ path = p+1;
+ }
+ return v;
+}
+
+void
+PySys_SetPath(const wchar_t *path)
+{
+ PyObject *v;
+ if ((v = makepathobject(path, DELIM)) == NULL)
+ Py_FatalError("can't create sys.path");
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (sys_set_object_id(tstate, &PyId_path, v) != 0) {
+ Py_FatalError("can't assign sys.path");
+ }
+ Py_DECREF(v);
+}
+
+static PyObject *
+make_sys_argv(int argc, wchar_t * const * argv)
+{
+ PyObject *list = PyList_New(argc);
+ if (list == NULL) {
+ return NULL;
+ }
+
+ for (Py_ssize_t i = 0; i < argc; i++) {
+ PyObject *v = PyUnicode_FromWideChar(argv[i], -1);
+ if (v == NULL) {
+ Py_DECREF(list);
+ return NULL;
+ }
+ PyList_SET_ITEM(list, i, v);
+ }
+ return list;
+}
+
+void
+PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
+{
+ wchar_t* empty_argv[1] = {L""};
+ PyThreadState *tstate = _PyThreadState_GET();
+
+ if (argc < 1 || argv == NULL) {
+ /* Ensure at least one (empty) argument is seen */
+ argv = empty_argv;
+ argc = 1;
+ }
+
+ PyObject *av = make_sys_argv(argc, argv);
+ if (av == NULL) {
+ Py_FatalError("no mem for sys.argv");
+ }
+ if (sys_set_object(tstate, "argv", av) != 0) {
+ Py_DECREF(av);
+ Py_FatalError("can't assign sys.argv");
+ }
+ Py_DECREF(av);
+
+ if (updatepath) {
+ /* If argv[0] is not '-c' nor '-m', prepend argv[0] to sys.path.
+ If argv[0] is a symlink, use the real path. */
+ const PyWideStringList argv_list = {.length = argc, .items = argv};
+ PyObject *path0 = NULL;
+ if (_PyPathConfig_ComputeSysPath0(&argv_list, &path0)) {
+ if (path0 == NULL) {
+ Py_FatalError("can't compute path0 from argv");
+ }
+
+ PyObject *sys_path = sys_get_object_id(tstate, &PyId_path);
+ if (sys_path != NULL) {
+ if (PyList_Insert(sys_path, 0, path0) < 0) {
+ Py_DECREF(path0);
+ Py_FatalError("can't prepend path0 to sys.path");
+ }
+ }
+ Py_DECREF(path0);
+ }
+ }
+}
+
+void
+PySys_SetArgv(int argc, wchar_t **argv)
+{
+ PySys_SetArgvEx(argc, argv, 0);
+}
+
+/* Reimplementation of PyFile_WriteString() no calling indirectly
+ PyErr_CheckSignals(): avoid the call to PyObject_Str(). */
+
+static int
+sys_pyfile_write_unicode(PyObject *unicode, PyObject *file)
+{
+ if (file == NULL)
+ return -1;
+ assert(unicode != NULL);
+ PyObject *result = _PyObject_CallMethodIdOneArg(file, &PyId_write, unicode);
+ if (result == NULL) {
+ return -1;
+ }
+ Py_DECREF(result);
+ return 0;
+}
+
+static int
+sys_pyfile_write(const char *text, PyObject *file)
+{
+ PyObject *unicode = NULL;
+ int err;
+
+ if (file == NULL)
+ return -1;
+
+ unicode = PyUnicode_FromString(text);
+ if (unicode == NULL)
+ return -1;
+
+ err = sys_pyfile_write_unicode(unicode, file);
+ Py_DECREF(unicode);
+ return err;
+}
+
+/* APIs to write to sys.stdout or sys.stderr using a printf-like interface.
+ Adapted from code submitted by Just van Rossum.
+
+ PySys_WriteStdout(format, ...)
+ PySys_WriteStderr(format, ...)
+
+ The first function writes to sys.stdout; the second to sys.stderr. When
+ there is a problem, they write to the real (C level) stdout or stderr;
+ no exceptions are raised.
+
+ PyErr_CheckSignals() is not called to avoid the execution of the Python
+ signal handlers: they may raise a new exception whereas sys_write()
+ ignores all exceptions.
+
+ Both take a printf-style format string as their first argument followed
+ by a variable length argument list determined by the format string.
+
+ *** WARNING ***
+
+ The format should limit the total size of the formatted output string to
+ 1000 bytes. In particular, this means that no unrestricted "%s" formats
+ should occur; these should be limited using "%.<N>s where <N> is a
+ decimal number calculated so that <N> plus the maximum size of other
+ formatted text does not exceed 1000 bytes. Also watch out for "%f",
+ which can print hundreds of digits for very large numbers.
+
+ */
+
+static void
+sys_write(_Py_Identifier *key, FILE *fp, const char *format, va_list va)
+{
+ PyObject *file;
+ PyObject *error_type, *error_value, *error_traceback;
+ char buffer[1001];
+ int written;
+ PyThreadState *tstate = _PyThreadState_GET();
+
+ _PyErr_Fetch(tstate, &error_type, &error_value, &error_traceback);
+ file = sys_get_object_id(tstate, key);
+ written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va);
+ if (sys_pyfile_write(buffer, file) != 0) {
+ _PyErr_Clear(tstate);
+ fputs(buffer, fp);
+ }
+ if (written < 0 || (size_t)written >= sizeof(buffer)) {
+ const char *truncated = "... truncated";
+ if (sys_pyfile_write(truncated, file) != 0)
+ fputs(truncated, fp);
+ }
+ _PyErr_Restore(tstate, error_type, error_value, error_traceback);
+}
+
+void
+PySys_WriteStdout(const char *format, ...)
+{
+ va_list va;
+
+ va_start(va, format);
+ sys_write(&PyId_stdout, stdout, format, va);
+ va_end(va);
+}
+
+void
+PySys_WriteStderr(const char *format, ...)
+{
+ va_list va;
+
+ va_start(va, format);
+ sys_write(&PyId_stderr, stderr, format, va);
+ va_end(va);
+}
+
+static void
+sys_format(_Py_Identifier *key, FILE *fp, const char *format, va_list va)
+{
+ PyObject *file, *message;
+ PyObject *error_type, *error_value, *error_traceback;
+ const char *utf8;
+ PyThreadState *tstate = _PyThreadState_GET();
+
+ _PyErr_Fetch(tstate, &error_type, &error_value, &error_traceback);
+ file = sys_get_object_id(tstate, key);
+ message = PyUnicode_FromFormatV(format, va);
+ if (message != NULL) {
+ if (sys_pyfile_write_unicode(message, file) != 0) {
+ _PyErr_Clear(tstate);
+ utf8 = PyUnicode_AsUTF8(message);
+ if (utf8 != NULL)
+ fputs(utf8, fp);
+ }
+ Py_DECREF(message);
+ }
+ _PyErr_Restore(tstate, error_type, error_value, error_traceback);
+}
+
+void
+PySys_FormatStdout(const char *format, ...)
+{
+ va_list va;
+
+ va_start(va, format);
+ sys_format(&PyId_stdout, stdout, format, va);
+ va_end(va);
+}
+
+void
+PySys_FormatStderr(const char *format, ...)
+{
+ va_list va;
+
+ va_start(va, format);
+ sys_format(&PyId_stderr, stderr, format, va);
+ va_end(va);
+}
diff --git a/contrib/tools/python3/src/Python/thread.c b/contrib/tools/python3/src/Python/thread.c
new file mode 100644
index 00000000000..a10f5728dc0
--- /dev/null
+++ b/contrib/tools/python3/src/Python/thread.c
@@ -0,0 +1,226 @@
+
+/* Thread package.
+ This is intended to be usable independently from Python.
+ The implementation for system foobar is in a file thread_foobar.h
+ which is included by this file dependent on config settings.
+ Stuff shared by all thread_*.h files is collected here. */
+
+#include "Python.h"
+#include "pycore_pystate.h" // _PyInterpreterState_GET()
+
+#ifndef _POSIX_THREADS
+/* This means pthreads are not implemented in libc headers, hence the macro
+ not present in unistd.h. But they still can be implemented as an external
+ library (e.g. gnu pth in pthread emulation) */
+# ifdef HAVE_PTHREAD_H
+# include <pthread.h> /* _POSIX_THREADS */
+# endif
+#endif
+
+#ifndef DONT_HAVE_STDIO_H
+#include <stdio.h>
+#endif
+
+#include <stdlib.h>
+
+#ifndef _POSIX_THREADS
+
+/* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then
+ enough of the Posix threads package is implemented to support python
+ threads.
+
+ This is valid for HP-UX 11.23 running on an ia64 system. If needed, add
+ a check of __ia64 to verify that we're running on an ia64 system instead
+ of a pa-risc system.
+*/
+#ifdef __hpux
+#ifdef _SC_THREADS
+#define _POSIX_THREADS
+#endif
+#endif
+
+#endif /* _POSIX_THREADS */
+
+
+#ifdef Py_DEBUG
+static int thread_debug = 0;
+#define dprintf(args) (void)((thread_debug & 1) && printf args)
+#define d2printf(args) ((thread_debug & 8) && printf args)
+#else
+#define dprintf(args)
+#define d2printf(args)
+#endif
+
+static int initialized;
+
+static void PyThread__init_thread(void); /* Forward */
+
+void
+PyThread_init_thread(void)
+{
+#ifdef Py_DEBUG
+ const char *p = Py_GETENV("PYTHONTHREADDEBUG");
+
+ if (p) {
+ if (*p)
+ thread_debug = atoi(p);
+ else
+ thread_debug = 1;
+ }
+#endif /* Py_DEBUG */
+ if (initialized)
+ return;
+ initialized = 1;
+ dprintf(("PyThread_init_thread called\n"));
+ PyThread__init_thread();
+}
+
+#if defined(_POSIX_THREADS)
+# define PYTHREAD_NAME "pthread"
+# include "thread_pthread.h"
+#elif defined(NT_THREADS)
+# define PYTHREAD_NAME "nt"
+# include "thread_nt.h"
+#else
+# error "Require native threads. See https://bugs.python.org/issue31370"
+#endif
+
+
+/* return the current thread stack size */
+size_t
+PyThread_get_stacksize(void)
+{
+ return _PyInterpreterState_GET()->pythread_stacksize;
+}
+
+/* Only platforms defining a THREAD_SET_STACKSIZE() macro
+ in thread_<platform>.h support changing the stack size.
+ Return 0 if stack size is valid,
+ -1 if stack size value is invalid,
+ -2 if setting stack size is not supported. */
+int
+PyThread_set_stacksize(size_t size)
+{
+#if defined(THREAD_SET_STACKSIZE)
+ return THREAD_SET_STACKSIZE(size);
+#else
+ return -2;
+#endif
+}
+
+
+/* Thread Specific Storage (TSS) API
+
+ Cross-platform components of TSS API implementation.
+*/
+
+Py_tss_t *
+PyThread_tss_alloc(void)
+{
+ Py_tss_t *new_key = (Py_tss_t *)PyMem_RawMalloc(sizeof(Py_tss_t));
+ if (new_key == NULL) {
+ return NULL;
+ }
+ new_key->_is_initialized = 0;
+ return new_key;
+}
+
+void
+PyThread_tss_free(Py_tss_t *key)
+{
+ if (key != NULL) {
+ PyThread_tss_delete(key);
+ PyMem_RawFree((void *)key);
+ }
+}
+
+int
+PyThread_tss_is_created(Py_tss_t *key)
+{
+ assert(key != NULL);
+ return key->_is_initialized;
+}
+
+
+PyDoc_STRVAR(threadinfo__doc__,
+"sys.thread_info\n\
+\n\
+A named tuple holding information about the thread implementation.");
+
+static PyStructSequence_Field threadinfo_fields[] = {
+ {"name", "name of the thread implementation"},
+ {"lock", "name of the lock implementation"},
+ {"version", "name and version of the thread library"},
+ {0}
+};
+
+static PyStructSequence_Desc threadinfo_desc = {
+ "sys.thread_info", /* name */
+ threadinfo__doc__, /* doc */
+ threadinfo_fields, /* fields */
+ 3
+};
+
+static PyTypeObject ThreadInfoType;
+
+PyObject*
+PyThread_GetInfo(void)
+{
+ PyObject *threadinfo, *value;
+ int pos = 0;
+#if (defined(_POSIX_THREADS) && defined(HAVE_CONFSTR) \
+ && defined(_CS_GNU_LIBPTHREAD_VERSION))
+ char buffer[255];
+ int len;
+#endif
+
+ if (ThreadInfoType.tp_name == 0) {
+ if (PyStructSequence_InitType2(&ThreadInfoType, &threadinfo_desc) < 0)
+ return NULL;
+ }
+
+ threadinfo = PyStructSequence_New(&ThreadInfoType);
+ if (threadinfo == NULL)
+ return NULL;
+
+ value = PyUnicode_FromString(PYTHREAD_NAME);
+ if (value == NULL) {
+ Py_DECREF(threadinfo);
+ return NULL;
+ }
+ PyStructSequence_SET_ITEM(threadinfo, pos++, value);
+
+#ifdef _POSIX_THREADS
+#ifdef USE_SEMAPHORES
+ value = PyUnicode_FromString("semaphore");
+#else
+ value = PyUnicode_FromString("mutex+cond");
+#endif
+ if (value == NULL) {
+ Py_DECREF(threadinfo);
+ return NULL;
+ }
+#else
+ Py_INCREF(Py_None);
+ value = Py_None;
+#endif
+ PyStructSequence_SET_ITEM(threadinfo, pos++, value);
+
+#if (defined(_POSIX_THREADS) && defined(HAVE_CONFSTR) \
+ && defined(_CS_GNU_LIBPTHREAD_VERSION))
+ value = NULL;
+ len = confstr(_CS_GNU_LIBPTHREAD_VERSION, buffer, sizeof(buffer));
+ if (1 < len && (size_t)len < sizeof(buffer)) {
+ value = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
+ if (value == NULL)
+ PyErr_Clear();
+ }
+ if (value == NULL)
+#endif
+ {
+ Py_INCREF(Py_None);
+ value = Py_None;
+ }
+ PyStructSequence_SET_ITEM(threadinfo, pos++, value);
+ return threadinfo;
+}
diff --git a/contrib/tools/python3/src/Python/thread_nt.h b/contrib/tools/python3/src/Python/thread_nt.h
new file mode 100644
index 00000000000..0ce5e94f89b
--- /dev/null
+++ b/contrib/tools/python3/src/Python/thread_nt.h
@@ -0,0 +1,505 @@
+#include "pycore_interp.h" // _PyInterpreterState.pythread_stacksize
+
+/* This code implemented by [email protected] */
+/* Fast NonRecursiveMutex support by Yakov Markovitch, [email protected] */
+/* Eliminated some memory leaks, [email protected] */
+
+#include <windows.h>
+#include <limits.h>
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+/* options */
+#ifndef _PY_USE_CV_LOCKS
+#define _PY_USE_CV_LOCKS 1 /* use locks based on cond vars */
+#endif
+
+/* Now, define a non-recursive mutex using either condition variables
+ * and critical sections (fast) or using operating system mutexes
+ * (slow)
+ */
+
+#if _PY_USE_CV_LOCKS
+
+#include "condvar.h"
+
+typedef struct _NRMUTEX
+{
+ PyMUTEX_T cs;
+ PyCOND_T cv;
+ int locked;
+} NRMUTEX;
+typedef NRMUTEX *PNRMUTEX;
+
+PNRMUTEX
+AllocNonRecursiveMutex()
+{
+ PNRMUTEX m = (PNRMUTEX)PyMem_RawMalloc(sizeof(NRMUTEX));
+ if (!m)
+ return NULL;
+ if (PyCOND_INIT(&m->cv))
+ goto fail;
+ if (PyMUTEX_INIT(&m->cs)) {
+ PyCOND_FINI(&m->cv);
+ goto fail;
+ }
+ m->locked = 0;
+ return m;
+fail:
+ PyMem_RawFree(m);
+ return NULL;
+}
+
+VOID
+FreeNonRecursiveMutex(PNRMUTEX mutex)
+{
+ if (mutex) {
+ PyCOND_FINI(&mutex->cv);
+ PyMUTEX_FINI(&mutex->cs);
+ PyMem_RawFree(mutex);
+ }
+}
+
+DWORD
+EnterNonRecursiveMutex(PNRMUTEX mutex, DWORD milliseconds)
+{
+ DWORD result = WAIT_OBJECT_0;
+ if (PyMUTEX_LOCK(&mutex->cs))
+ return WAIT_FAILED;
+ if (milliseconds == INFINITE) {
+ while (mutex->locked) {
+ if (PyCOND_WAIT(&mutex->cv, &mutex->cs)) {
+ result = WAIT_FAILED;
+ break;
+ }
+ }
+ } else if (milliseconds != 0) {
+ /* wait at least until the target */
+ _PyTime_t now = _PyTime_GetPerfCounter();
+ if (now <= 0) {
+ Py_FatalError("_PyTime_GetPerfCounter() == 0");
+ }
+ _PyTime_t nanoseconds = _PyTime_FromNanoseconds((_PyTime_t)milliseconds * 1000000);
+ _PyTime_t target = now + nanoseconds;
+ while (mutex->locked) {
+ _PyTime_t microseconds = _PyTime_AsMicroseconds(nanoseconds, _PyTime_ROUND_TIMEOUT);
+ if (PyCOND_TIMEDWAIT(&mutex->cv, &mutex->cs, microseconds) < 0) {
+ result = WAIT_FAILED;
+ break;
+ }
+ now = _PyTime_GetPerfCounter();
+ if (target <= now)
+ break;
+ nanoseconds = target - now;
+ }
+ }
+ if (!mutex->locked) {
+ mutex->locked = 1;
+ result = WAIT_OBJECT_0;
+ } else if (result == WAIT_OBJECT_0)
+ result = WAIT_TIMEOUT;
+ /* else, it is WAIT_FAILED */
+ PyMUTEX_UNLOCK(&mutex->cs); /* must ignore result here */
+ return result;
+}
+
+BOOL
+LeaveNonRecursiveMutex(PNRMUTEX mutex)
+{
+ BOOL result;
+ if (PyMUTEX_LOCK(&mutex->cs))
+ return FALSE;
+ mutex->locked = 0;
+ /* condvar APIs return 0 on success. We need to return TRUE on success. */
+ result = !PyCOND_SIGNAL(&mutex->cv);
+ PyMUTEX_UNLOCK(&mutex->cs);
+ return result;
+}
+
+#else /* if ! _PY_USE_CV_LOCKS */
+
+/* NR-locks based on a kernel mutex */
+#define PNRMUTEX HANDLE
+
+PNRMUTEX
+AllocNonRecursiveMutex()
+{
+ return CreateSemaphore(NULL, 1, 1, NULL);
+}
+
+VOID
+FreeNonRecursiveMutex(PNRMUTEX mutex)
+{
+ /* No in-use check */
+ CloseHandle(mutex);
+}
+
+DWORD
+EnterNonRecursiveMutex(PNRMUTEX mutex, DWORD milliseconds)
+{
+ return WaitForSingleObjectEx(mutex, milliseconds, FALSE);
+}
+
+BOOL
+LeaveNonRecursiveMutex(PNRMUTEX mutex)
+{
+ return ReleaseSemaphore(mutex, 1, NULL);
+}
+#endif /* _PY_USE_CV_LOCKS */
+
+unsigned long PyThread_get_thread_ident(void);
+
+#ifdef PY_HAVE_THREAD_NATIVE_ID
+unsigned long PyThread_get_thread_native_id(void);
+#endif
+
+/*
+ * Initialization of the C package, should not be needed.
+ */
+static void
+PyThread__init_thread(void)
+{
+}
+
+/*
+ * Thread support.
+ */
+
+typedef struct {
+ void (*func)(void*);
+ void *arg;
+} callobj;
+
+/* thunker to call adapt between the function type used by the system's
+thread start function and the internally used one. */
+static unsigned __stdcall
+bootstrap(void *call)
+{
+ callobj *obj = (callobj*)call;
+ void (*func)(void*) = obj->func;
+ void *arg = obj->arg;
+ HeapFree(GetProcessHeap(), 0, obj);
+ func(arg);
+ return 0;
+}
+
+unsigned long
+PyThread_start_new_thread(void (*func)(void *), void *arg)
+{
+ HANDLE hThread;
+ unsigned threadID;
+ callobj *obj;
+
+ dprintf(("%lu: PyThread_start_new_thread called\n",
+ PyThread_get_thread_ident()));
+ if (!initialized)
+ PyThread_init_thread();
+
+ obj = (callobj*)HeapAlloc(GetProcessHeap(), 0, sizeof(*obj));
+ if (!obj)
+ return PYTHREAD_INVALID_THREAD_ID;
+ obj->func = func;
+ obj->arg = arg;
+ PyThreadState *tstate = _PyThreadState_GET();
+ size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0;
+ hThread = (HANDLE)_beginthreadex(0,
+ Py_SAFE_DOWNCAST(stacksize, Py_ssize_t, unsigned int),
+ bootstrap, obj,
+ 0, &threadID);
+ if (hThread == 0) {
+ /* I've seen errno == EAGAIN here, which means "there are
+ * too many threads".
+ */
+ int e = errno;
+ dprintf(("%lu: PyThread_start_new_thread failed, errno %d\n",
+ PyThread_get_thread_ident(), e));
+ threadID = (unsigned)-1;
+ HeapFree(GetProcessHeap(), 0, obj);
+ }
+ else {
+ dprintf(("%lu: PyThread_start_new_thread succeeded: %p\n",
+ PyThread_get_thread_ident(), (void*)hThread));
+ CloseHandle(hThread);
+ }
+ return threadID;
+}
+
+/*
+ * Return the thread Id instead of a handle. The Id is said to uniquely identify the
+ * thread in the system
+ */
+unsigned long
+PyThread_get_thread_ident(void)
+{
+ if (!initialized)
+ PyThread_init_thread();
+
+ return GetCurrentThreadId();
+}
+
+#ifdef PY_HAVE_THREAD_NATIVE_ID
+/*
+ * Return the native Thread ID (TID) of the calling thread.
+ * The native ID of a thread is valid and guaranteed to be unique system-wide
+ * from the time the thread is created until the thread has been terminated.
+ */
+unsigned long
+PyThread_get_thread_native_id(void)
+{
+ if (!initialized) {
+ PyThread_init_thread();
+ }
+
+ DWORD native_id;
+ native_id = GetCurrentThreadId();
+ return (unsigned long) native_id;
+}
+#endif
+
+void _Py_NO_RETURN
+PyThread_exit_thread(void)
+{
+ dprintf(("%lu: PyThread_exit_thread called\n", PyThread_get_thread_ident()));
+ if (!initialized)
+ exit(0);
+ _endthreadex(0);
+}
+
+/*
+ * Lock support. It has to be implemented as semaphores.
+ * I [Dag] tried to implement it with mutex but I could find a way to
+ * tell whether a thread already own the lock or not.
+ */
+PyThread_type_lock
+PyThread_allocate_lock(void)
+{
+ PNRMUTEX aLock;
+
+ dprintf(("PyThread_allocate_lock called\n"));
+ if (!initialized)
+ PyThread_init_thread();
+
+ aLock = AllocNonRecursiveMutex() ;
+
+ dprintf(("%lu: PyThread_allocate_lock() -> %p\n", PyThread_get_thread_ident(), aLock));
+
+ return (PyThread_type_lock) aLock;
+}
+
+void
+PyThread_free_lock(PyThread_type_lock aLock)
+{
+ dprintf(("%lu: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
+
+ FreeNonRecursiveMutex(aLock) ;
+}
+
+/*
+ * Return 1 on success if the lock was acquired
+ *
+ * and 0 if the lock was not acquired. This means a 0 is returned
+ * if the lock has already been acquired by this thread!
+ */
+PyLockStatus
+PyThread_acquire_lock_timed(PyThread_type_lock aLock,
+ PY_TIMEOUT_T microseconds, int intr_flag)
+{
+ /* Fow now, intr_flag does nothing on Windows, and lock acquires are
+ * uninterruptible. */
+ PyLockStatus success;
+ PY_TIMEOUT_T milliseconds;
+
+ if (microseconds >= 0) {
+ milliseconds = microseconds / 1000;
+ if (microseconds % 1000 > 0)
+ ++milliseconds;
+ if (milliseconds > PY_DWORD_MAX) {
+ Py_FatalError("Timeout larger than PY_TIMEOUT_MAX");
+ }
+ }
+ else {
+ milliseconds = INFINITE;
+ }
+
+ dprintf(("%lu: PyThread_acquire_lock_timed(%p, %lld) called\n",
+ PyThread_get_thread_ident(), aLock, microseconds));
+
+ if (aLock && EnterNonRecursiveMutex((PNRMUTEX)aLock,
+ (DWORD)milliseconds) == WAIT_OBJECT_0) {
+ success = PY_LOCK_ACQUIRED;
+ }
+ else {
+ success = PY_LOCK_FAILURE;
+ }
+
+ dprintf(("%lu: PyThread_acquire_lock(%p, %lld) -> %d\n",
+ PyThread_get_thread_ident(), aLock, microseconds, success));
+
+ return success;
+}
+int
+PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
+{
+ return PyThread_acquire_lock_timed(aLock, waitflag ? -1 : 0, 0);
+}
+
+void
+PyThread_release_lock(PyThread_type_lock aLock)
+{
+ dprintf(("%lu: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
+
+ if (!(aLock && LeaveNonRecursiveMutex((PNRMUTEX) aLock)))
+ dprintf(("%lu: Could not PyThread_release_lock(%p) error: %ld\n", PyThread_get_thread_ident(), aLock, GetLastError()));
+}
+
+/* minimum/maximum thread stack sizes supported */
+#define THREAD_MIN_STACKSIZE 0x8000 /* 32 KiB */
+#define THREAD_MAX_STACKSIZE 0x10000000 /* 256 MiB */
+
+/* set the thread stack size.
+ * Return 0 if size is valid, -1 otherwise.
+ */
+static int
+_pythread_nt_set_stacksize(size_t size)
+{
+ /* set to default */
+ if (size == 0) {
+ _PyInterpreterState_GET()->pythread_stacksize = 0;
+ return 0;
+ }
+
+ /* valid range? */
+ if (size >= THREAD_MIN_STACKSIZE && size < THREAD_MAX_STACKSIZE) {
+ _PyInterpreterState_GET()->pythread_stacksize = size;
+ return 0;
+ }
+
+ return -1;
+}
+
+#define THREAD_SET_STACKSIZE(x) _pythread_nt_set_stacksize(x)
+
+
+/* Thread Local Storage (TLS) API
+
+ This API is DEPRECATED since Python 3.7. See PEP 539 for details.
+*/
+
+int
+PyThread_create_key(void)
+{
+ DWORD result = TlsAlloc();
+ if (result == TLS_OUT_OF_INDEXES)
+ return -1;
+ return (int)result;
+}
+
+void
+PyThread_delete_key(int key)
+{
+ TlsFree(key);
+}
+
+int
+PyThread_set_key_value(int key, void *value)
+{
+ BOOL ok = TlsSetValue(key, value);
+ return ok ? 0 : -1;
+}
+
+void *
+PyThread_get_key_value(int key)
+{
+ /* because TLS is used in the Py_END_ALLOW_THREAD macro,
+ * it is necessary to preserve the windows error state, because
+ * it is assumed to be preserved across the call to the macro.
+ * Ideally, the macro should be fixed, but it is simpler to
+ * do it here.
+ */
+ DWORD error = GetLastError();
+ void *result = TlsGetValue(key);
+ SetLastError(error);
+ return result;
+}
+
+void
+PyThread_delete_key_value(int key)
+{
+ /* NULL is used as "key missing", and it is also the default
+ * given by TlsGetValue() if nothing has been set yet.
+ */
+ TlsSetValue(key, NULL);
+}
+
+
+/* reinitialization of TLS is not necessary after fork when using
+ * the native TLS functions. And forking isn't supported on Windows either.
+ */
+void
+PyThread_ReInitTLS(void)
+{
+}
+
+
+/* Thread Specific Storage (TSS) API
+
+ Platform-specific components of TSS API implementation.
+*/
+
+int
+PyThread_tss_create(Py_tss_t *key)
+{
+ assert(key != NULL);
+ /* If the key has been created, function is silently skipped. */
+ if (key->_is_initialized) {
+ return 0;
+ }
+
+ DWORD result = TlsAlloc();
+ if (result == TLS_OUT_OF_INDEXES) {
+ return -1;
+ }
+ /* In Windows, platform-specific key type is DWORD. */
+ key->_key = result;
+ key->_is_initialized = 1;
+ return 0;
+}
+
+void
+PyThread_tss_delete(Py_tss_t *key)
+{
+ assert(key != NULL);
+ /* If the key has not been created, function is silently skipped. */
+ if (!key->_is_initialized) {
+ return;
+ }
+
+ TlsFree(key->_key);
+ key->_key = TLS_OUT_OF_INDEXES;
+ key->_is_initialized = 0;
+}
+
+int
+PyThread_tss_set(Py_tss_t *key, void *value)
+{
+ assert(key != NULL);
+ BOOL ok = TlsSetValue(key->_key, value);
+ return ok ? 0 : -1;
+}
+
+void *
+PyThread_tss_get(Py_tss_t *key)
+{
+ assert(key != NULL);
+ /* because TSS is used in the Py_END_ALLOW_THREAD macro,
+ * it is necessary to preserve the windows error state, because
+ * it is assumed to be preserved across the call to the macro.
+ * Ideally, the macro should be fixed, but it is simpler to
+ * do it here.
+ */
+ DWORD error = GetLastError();
+ void *result = TlsGetValue(key->_key);
+ SetLastError(error);
+ return result;
+}
diff --git a/contrib/tools/python3/src/Python/thread_pthread.h b/contrib/tools/python3/src/Python/thread_pthread.h
new file mode 100644
index 00000000000..83974b4c0ca
--- /dev/null
+++ b/contrib/tools/python3/src/Python/thread_pthread.h
@@ -0,0 +1,926 @@
+#include "pycore_interp.h" // _PyInterpreterState.pythread_stacksize
+
+/* Posix threads interface */
+
+#include <stdlib.h>
+#include <string.h>
+#if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
+#define destructor xxdestructor
+#endif
+#include <pthread.h>
+#if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
+#undef destructor
+#endif
+#include <signal.h>
+
+#if defined(__linux__)
+# include <sys/syscall.h> /* syscall(SYS_gettid) */
+#elif defined(__FreeBSD__)
+# include <pthread_np.h> /* pthread_getthreadid_np() */
+#elif defined(__OpenBSD__)
+# include <unistd.h> /* getthrid() */
+#elif defined(_AIX)
+# include <sys/thread.h> /* thread_self() */
+#elif defined(__NetBSD__)
+# include <lwp.h> /* _lwp_self() */
+#endif
+
+/* The POSIX spec requires that use of pthread_attr_setstacksize
+ be conditional on _POSIX_THREAD_ATTR_STACKSIZE being defined. */
+#ifdef _POSIX_THREAD_ATTR_STACKSIZE
+#ifndef THREAD_STACK_SIZE
+#define THREAD_STACK_SIZE 0 /* use default stack size */
+#endif
+
+/* The default stack size for new threads on OSX and BSD is small enough that
+ * we'll get hard crashes instead of 'maximum recursion depth exceeded'
+ * exceptions.
+ *
+ * The default stack sizes below are the empirically determined minimal stack
+ * sizes where a simple recursive function doesn't cause a hard crash.
+ */
+#if defined(__APPLE__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
+#undef THREAD_STACK_SIZE
+/* Note: This matches the value of -Wl,-stack_size in configure.ac */
+#define THREAD_STACK_SIZE 0x1000000
+#endif
+#if defined(__FreeBSD__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
+#undef THREAD_STACK_SIZE
+#define THREAD_STACK_SIZE 0x400000
+#endif
+#if defined(_AIX) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
+#undef THREAD_STACK_SIZE
+#define THREAD_STACK_SIZE 0x200000
+#endif
+/* bpo-38852: test_threading.test_recursion_limit() checks that 1000 recursive
+ Python calls (default recursion limit) doesn't crash, but raise a regular
+ RecursionError exception. In debug mode, Python function calls allocates
+ more memory on the stack, so use a stack of 8 MiB. */
+#if defined(__ANDROID__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
+# ifdef Py_DEBUG
+# undef THREAD_STACK_SIZE
+# define THREAD_STACK_SIZE 0x800000
+# endif
+#endif
+/* for safety, ensure a viable minimum stacksize */
+#define THREAD_STACK_MIN 0x8000 /* 32 KiB */
+#else /* !_POSIX_THREAD_ATTR_STACKSIZE */
+#ifdef THREAD_STACK_SIZE
+#error "THREAD_STACK_SIZE defined but _POSIX_THREAD_ATTR_STACKSIZE undefined"
+#endif
+#endif
+
+/* The POSIX spec says that implementations supporting the sem_*
+ family of functions must indicate this by defining
+ _POSIX_SEMAPHORES. */
+#ifdef _POSIX_SEMAPHORES
+/* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so
+ we need to add 0 to make it work there as well. */
+#if (_POSIX_SEMAPHORES+0) == -1
+#define HAVE_BROKEN_POSIX_SEMAPHORES
+#else
+#include <semaphore.h>
+#include <errno.h>
+#endif
+#endif
+
+
+/* Whether or not to use semaphores directly rather than emulating them with
+ * mutexes and condition variables:
+ */
+#if (defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) && \
+ (defined(HAVE_SEM_TIMEDWAIT) || defined(HAVE_SEM_CLOCKWAIT)))
+# define USE_SEMAPHORES
+#else
+# undef USE_SEMAPHORES
+#endif
+
+#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
+// monotonic is supported statically. It doesn't mean it works on runtime.
+#define CONDATTR_MONOTONIC
+#endif
+
+
+/* On platforms that don't use standard POSIX threads pthread_sigmask()
+ * isn't present. DEC threads uses sigprocmask() instead as do most
+ * other UNIX International compliant systems that don't have the full
+ * pthread implementation.
+ */
+#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
+# define SET_THREAD_SIGMASK pthread_sigmask
+#else
+# define SET_THREAD_SIGMASK sigprocmask
+#endif
+
+
+#define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \
+do { \
+ struct timeval tv; \
+ gettimeofday(&tv, NULL); \
+ tv.tv_usec += microseconds % 1000000; \
+ tv.tv_sec += microseconds / 1000000; \
+ tv.tv_sec += tv.tv_usec / 1000000; \
+ tv.tv_usec %= 1000000; \
+ ts.tv_sec = tv.tv_sec; \
+ ts.tv_nsec = tv.tv_usec * 1000; \
+} while(0)
+
+#if defined(CONDATTR_MONOTONIC) || defined(HAVE_SEM_CLOCKWAIT)
+static void
+monotonic_abs_timeout(long long us, struct timespec *abs)
+{
+ clock_gettime(CLOCK_MONOTONIC, abs);
+ abs->tv_sec += us / 1000000;
+ abs->tv_nsec += (us % 1000000) * 1000;
+ abs->tv_sec += abs->tv_nsec / 1000000000;
+ abs->tv_nsec %= 1000000000;
+}
+#endif
+
+
+/*
+ * pthread_cond support
+ */
+
+// NULL when pthread_condattr_setclock(CLOCK_MONOTONIC) is not supported.
+static pthread_condattr_t *condattr_monotonic = NULL;
+
+static void
+init_condattr(void)
+{
+#ifdef CONDATTR_MONOTONIC
+ static pthread_condattr_t ca;
+ pthread_condattr_init(&ca);
+ if (pthread_condattr_setclock(&ca, CLOCK_MONOTONIC) == 0) {
+ condattr_monotonic = &ca; // Use monotonic clock
+ }
+#endif
+}
+
+int
+_PyThread_cond_init(PyCOND_T *cond)
+{
+ return pthread_cond_init(cond, condattr_monotonic);
+}
+
+
+void
+_PyThread_cond_after(long long us, struct timespec *abs)
+{
+#ifdef CONDATTR_MONOTONIC
+ if (condattr_monotonic) {
+ monotonic_abs_timeout(us, abs);
+ return;
+ }
+#endif
+
+ struct timespec ts;
+ MICROSECONDS_TO_TIMESPEC(us, ts);
+ *abs = ts;
+}
+
+
+/* A pthread mutex isn't sufficient to model the Python lock type
+ * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
+ * following are undefined:
+ * -> a thread tries to lock a mutex it already has locked
+ * -> a thread tries to unlock a mutex locked by a different thread
+ * pthread mutexes are designed for serializing threads over short pieces
+ * of code anyway, so wouldn't be an appropriate implementation of
+ * Python's locks regardless.
+ *
+ * The pthread_lock struct implements a Python lock as a "locked?" bit
+ * and a <condition, mutex> pair. In general, if the bit can be acquired
+ * instantly, it is, else the pair is used to block the thread until the
+ * bit is cleared. 9 May 1994 [email protected]
+ */
+
+typedef struct {
+ char locked; /* 0=unlocked, 1=locked */
+ /* a <cond, mutex> pair to handle an acquire of a locked lock */
+ pthread_cond_t lock_released;
+ pthread_mutex_t mut;
+} pthread_lock;
+
+#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
+#define CHECK_STATUS_PTHREAD(name) if (status != 0) { fprintf(stderr, \
+ "%s: %s\n", name, strerror(status)); error = 1; }
+
+/*
+ * Initialization.
+ */
+static void
+PyThread__init_thread(void)
+{
+#if defined(_AIX) && defined(__GNUC__)
+ extern void pthread_init(void);
+ pthread_init();
+#endif
+ init_condattr();
+}
+
+/*
+ * Thread support.
+ */
+
+/* bpo-33015: pythread_callback struct and pythread_wrapper() cast
+ "void func(void *)" to "void* func(void *)": always return NULL.
+
+ PyThread_start_new_thread() uses "void func(void *)" type, whereas
+ pthread_create() requires a void* return value. */
+typedef struct {
+ void (*func) (void *);
+ void *arg;
+} pythread_callback;
+
+static void *
+pythread_wrapper(void *arg)
+{
+ /* copy func and func_arg and free the temporary structure */
+ pythread_callback *callback = arg;
+ void (*func)(void *) = callback->func;
+ void *func_arg = callback->arg;
+ PyMem_RawFree(arg);
+
+ func(func_arg);
+ return NULL;
+}
+
+unsigned long
+PyThread_start_new_thread(void (*func)(void *), void *arg)
+{
+ pthread_t th;
+ int status;
+#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
+ pthread_attr_t attrs;
+#endif
+#if defined(THREAD_STACK_SIZE)
+ size_t tss;
+#endif
+
+ dprintf(("PyThread_start_new_thread called\n"));
+ if (!initialized)
+ PyThread_init_thread();
+
+#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
+ if (pthread_attr_init(&attrs) != 0)
+ return PYTHREAD_INVALID_THREAD_ID;
+#endif
+#if defined(THREAD_STACK_SIZE)
+ PyThreadState *tstate = _PyThreadState_GET();
+ size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0;
+ tss = (stacksize != 0) ? stacksize : THREAD_STACK_SIZE;
+ if (tss != 0) {
+ if (pthread_attr_setstacksize(&attrs, tss) != 0) {
+ pthread_attr_destroy(&attrs);
+ return PYTHREAD_INVALID_THREAD_ID;
+ }
+ }
+#endif
+#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
+ pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
+#endif
+
+ pythread_callback *callback = PyMem_RawMalloc(sizeof(pythread_callback));
+
+ if (callback == NULL) {
+ return PYTHREAD_INVALID_THREAD_ID;
+ }
+
+ callback->func = func;
+ callback->arg = arg;
+
+ status = pthread_create(&th,
+#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
+ &attrs,
+#else
+ (pthread_attr_t*)NULL,
+#endif
+ pythread_wrapper, callback);
+
+#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
+ pthread_attr_destroy(&attrs);
+#endif
+
+ if (status != 0) {
+ PyMem_RawFree(callback);
+ return PYTHREAD_INVALID_THREAD_ID;
+ }
+
+ pthread_detach(th);
+
+#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
+ return (unsigned long) th;
+#else
+ return (unsigned long) *(unsigned long *) &th;
+#endif
+}
+
+/* XXX This implementation is considered (to quote Tim Peters) "inherently
+ hosed" because:
+ - It does not guarantee the promise that a non-zero integer is returned.
+ - The cast to unsigned long is inherently unsafe.
+ - It is not clear that the 'volatile' (for AIX?) are any longer necessary.
+*/
+unsigned long
+PyThread_get_thread_ident(void)
+{
+ volatile pthread_t threadid;
+ if (!initialized)
+ PyThread_init_thread();
+ threadid = pthread_self();
+ return (unsigned long) threadid;
+}
+
+#ifdef PY_HAVE_THREAD_NATIVE_ID
+unsigned long
+PyThread_get_thread_native_id(void)
+{
+ if (!initialized)
+ PyThread_init_thread();
+#ifdef __APPLE__
+ uint64_t native_id;
+ (void) pthread_threadid_np(NULL, &native_id);
+#elif defined(__linux__)
+ pid_t native_id;
+ native_id = syscall(SYS_gettid);
+#elif defined(__FreeBSD__)
+ int native_id;
+ native_id = pthread_getthreadid_np();
+#elif defined(__OpenBSD__)
+ pid_t native_id;
+ native_id = getthrid();
+#elif defined(_AIX)
+ tid_t native_id;
+ native_id = thread_self();
+#elif defined(__NetBSD__)
+ lwpid_t native_id;
+ native_id = _lwp_self();
+#endif
+ return (unsigned long) native_id;
+}
+#endif
+
+void _Py_NO_RETURN
+PyThread_exit_thread(void)
+{
+ dprintf(("PyThread_exit_thread called\n"));
+ if (!initialized)
+ exit(0);
+ pthread_exit(0);
+}
+
+#ifdef USE_SEMAPHORES
+
+/*
+ * Lock support.
+ */
+
+PyThread_type_lock
+PyThread_allocate_lock(void)
+{
+ sem_t *lock;
+ int status, error = 0;
+
+ dprintf(("PyThread_allocate_lock called\n"));
+ if (!initialized)
+ PyThread_init_thread();
+
+ lock = (sem_t *)PyMem_RawMalloc(sizeof(sem_t));
+
+ if (lock) {
+ status = sem_init(lock,0,1);
+ CHECK_STATUS("sem_init");
+
+ if (error) {
+ PyMem_RawFree((void *)lock);
+ lock = NULL;
+ }
+ }
+
+ dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
+ return (PyThread_type_lock)lock;
+}
+
+void
+PyThread_free_lock(PyThread_type_lock lock)
+{
+ sem_t *thelock = (sem_t *)lock;
+ int status, error = 0;
+
+ (void) error; /* silence unused-but-set-variable warning */
+ dprintf(("PyThread_free_lock(%p) called\n", lock));
+
+ if (!thelock)
+ return;
+
+ status = sem_destroy(thelock);
+ CHECK_STATUS("sem_destroy");
+
+ PyMem_RawFree((void *)thelock);
+}
+
+/*
+ * As of February 2002, Cygwin thread implementations mistakenly report error
+ * codes in the return value of the sem_ calls (like the pthread_ functions).
+ * Correct implementations return -1 and put the code in errno. This supports
+ * either.
+ */
+static int
+fix_status(int status)
+{
+ return (status == -1) ? errno : status;
+}
+
+PyLockStatus
+PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
+ int intr_flag)
+{
+ PyLockStatus success;
+ sem_t *thelock = (sem_t *)lock;
+ int status, error = 0;
+ struct timespec ts;
+#ifndef HAVE_SEM_CLOCKWAIT
+ _PyTime_t deadline = 0;
+#endif
+
+ (void) error; /* silence unused-but-set-variable warning */
+ dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
+ lock, microseconds, intr_flag));
+
+ if (microseconds > PY_TIMEOUT_MAX) {
+ Py_FatalError("Timeout larger than PY_TIMEOUT_MAX");
+ }
+
+ if (microseconds > 0) {
+#ifdef HAVE_SEM_CLOCKWAIT
+ monotonic_abs_timeout(microseconds, &ts);
+#else
+ MICROSECONDS_TO_TIMESPEC(microseconds, ts);
+
+ if (!intr_flag) {
+ /* cannot overflow thanks to (microseconds > PY_TIMEOUT_MAX)
+ check done above */
+ _PyTime_t timeout = _PyTime_FromNanoseconds(microseconds * 1000);
+ deadline = _PyTime_GetMonotonicClock() + timeout;
+ }
+#endif
+ }
+
+ while (1) {
+ if (microseconds > 0) {
+#ifdef HAVE_SEM_CLOCKWAIT
+ status = fix_status(sem_clockwait(thelock, CLOCK_MONOTONIC,
+ &ts));
+#else
+ status = fix_status(sem_timedwait(thelock, &ts));
+#endif
+ }
+ else if (microseconds == 0) {
+ status = fix_status(sem_trywait(thelock));
+ }
+ else {
+ status = fix_status(sem_wait(thelock));
+ }
+
+ /* Retry if interrupted by a signal, unless the caller wants to be
+ notified. */
+ if (intr_flag || status != EINTR) {
+ break;
+ }
+
+ // sem_clockwait() uses an absolute timeout, there is no need
+ // to recompute the relative timeout.
+#ifndef HAVE_SEM_CLOCKWAIT
+ if (microseconds > 0) {
+ /* wait interrupted by a signal (EINTR): recompute the timeout */
+ _PyTime_t dt = deadline - _PyTime_GetMonotonicClock();
+ if (dt < 0) {
+ status = ETIMEDOUT;
+ break;
+ }
+ else if (dt > 0) {
+ _PyTime_t realtime_deadline = _PyTime_GetSystemClock() + dt;
+ if (_PyTime_AsTimespec(realtime_deadline, &ts) < 0) {
+ /* Cannot occur thanks to (microseconds > PY_TIMEOUT_MAX)
+ check done above */
+ Py_UNREACHABLE();
+ }
+ /* no need to update microseconds value, the code only care
+ if (microseconds > 0 or (microseconds == 0). */
+ }
+ else {
+ microseconds = 0;
+ }
+ }
+#endif
+ }
+
+ /* Don't check the status if we're stopping because of an interrupt. */
+ if (!(intr_flag && status == EINTR)) {
+ if (microseconds > 0) {
+ if (status != ETIMEDOUT) {
+#ifdef HAVE_SEM_CLOCKWAIT
+ CHECK_STATUS("sem_clockwait");
+#else
+ CHECK_STATUS("sem_timedwait");
+#endif
+ }
+ }
+ else if (microseconds == 0) {
+ if (status != EAGAIN)
+ CHECK_STATUS("sem_trywait");
+ }
+ else {
+ CHECK_STATUS("sem_wait");
+ }
+ }
+
+ if (status == 0) {
+ success = PY_LOCK_ACQUIRED;
+ } else if (intr_flag && status == EINTR) {
+ success = PY_LOCK_INTR;
+ } else {
+ success = PY_LOCK_FAILURE;
+ }
+
+ dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
+ lock, microseconds, intr_flag, success));
+ return success;
+}
+
+void
+PyThread_release_lock(PyThread_type_lock lock)
+{
+ sem_t *thelock = (sem_t *)lock;
+ int status, error = 0;
+
+ (void) error; /* silence unused-but-set-variable warning */
+ dprintf(("PyThread_release_lock(%p) called\n", lock));
+
+ status = sem_post(thelock);
+ CHECK_STATUS("sem_post");
+}
+
+#else /* USE_SEMAPHORES */
+
+/*
+ * Lock support.
+ */
+PyThread_type_lock
+PyThread_allocate_lock(void)
+{
+ pthread_lock *lock;
+ int status, error = 0;
+
+ dprintf(("PyThread_allocate_lock called\n"));
+ if (!initialized)
+ PyThread_init_thread();
+
+ lock = (pthread_lock *) PyMem_RawCalloc(1, sizeof(pthread_lock));
+ if (lock) {
+ lock->locked = 0;
+
+ status = pthread_mutex_init(&lock->mut, NULL);
+ CHECK_STATUS_PTHREAD("pthread_mutex_init");
+ /* Mark the pthread mutex underlying a Python mutex as
+ pure happens-before. We can't simply mark the
+ Python-level mutex as a mutex because it can be
+ acquired and released in different threads, which
+ will cause errors. */
+ _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut);
+
+ status = _PyThread_cond_init(&lock->lock_released);
+ CHECK_STATUS_PTHREAD("pthread_cond_init");
+
+ if (error) {
+ PyMem_RawFree((void *)lock);
+ lock = 0;
+ }
+ }
+
+ dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
+ return (PyThread_type_lock) lock;
+}
+
+void
+PyThread_free_lock(PyThread_type_lock lock)
+{
+ pthread_lock *thelock = (pthread_lock *)lock;
+ int status, error = 0;
+
+ (void) error; /* silence unused-but-set-variable warning */
+ dprintf(("PyThread_free_lock(%p) called\n", lock));
+
+ /* some pthread-like implementations tie the mutex to the cond
+ * and must have the cond destroyed first.
+ */
+ status = pthread_cond_destroy( &thelock->lock_released );
+ CHECK_STATUS_PTHREAD("pthread_cond_destroy");
+
+ status = pthread_mutex_destroy( &thelock->mut );
+ CHECK_STATUS_PTHREAD("pthread_mutex_destroy");
+
+ PyMem_RawFree((void *)thelock);
+}
+
+PyLockStatus
+PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
+ int intr_flag)
+{
+ PyLockStatus success = PY_LOCK_FAILURE;
+ pthread_lock *thelock = (pthread_lock *)lock;
+ int status, error = 0;
+
+ dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
+ lock, microseconds, intr_flag));
+
+ if (microseconds == 0) {
+ status = pthread_mutex_trylock( &thelock->mut );
+ if (status != EBUSY)
+ CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]");
+ }
+ else {
+ status = pthread_mutex_lock( &thelock->mut );
+ CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]");
+ }
+ if (status == 0) {
+ if (thelock->locked == 0) {
+ success = PY_LOCK_ACQUIRED;
+ }
+ else if (microseconds != 0) {
+ struct timespec abs;
+ if (microseconds > 0) {
+ _PyThread_cond_after(microseconds, &abs);
+ }
+ /* continue trying until we get the lock */
+
+ /* mut must be locked by me -- part of the condition
+ * protocol */
+ while (success == PY_LOCK_FAILURE) {
+ if (microseconds > 0) {
+ status = pthread_cond_timedwait(
+ &thelock->lock_released,
+ &thelock->mut, &abs);
+ if (status == 1) {
+ break;
+ }
+ if (status == ETIMEDOUT)
+ break;
+ CHECK_STATUS_PTHREAD("pthread_cond_timedwait");
+ }
+ else {
+ status = pthread_cond_wait(
+ &thelock->lock_released,
+ &thelock->mut);
+ CHECK_STATUS_PTHREAD("pthread_cond_wait");
+ }
+
+ if (intr_flag && status == 0 && thelock->locked) {
+ /* We were woken up, but didn't get the lock. We probably received
+ * a signal. Return PY_LOCK_INTR to allow the caller to handle
+ * it and retry. */
+ success = PY_LOCK_INTR;
+ break;
+ }
+ else if (status == 0 && !thelock->locked) {
+ success = PY_LOCK_ACQUIRED;
+ }
+ }
+ }
+ if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
+ status = pthread_mutex_unlock( &thelock->mut );
+ CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");
+ }
+
+ if (error) success = PY_LOCK_FAILURE;
+ dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
+ lock, microseconds, intr_flag, success));
+ return success;
+}
+
+void
+PyThread_release_lock(PyThread_type_lock lock)
+{
+ pthread_lock *thelock = (pthread_lock *)lock;
+ int status, error = 0;
+
+ (void) error; /* silence unused-but-set-variable warning */
+ dprintf(("PyThread_release_lock(%p) called\n", lock));
+
+ status = pthread_mutex_lock( &thelock->mut );
+ CHECK_STATUS_PTHREAD("pthread_mutex_lock[3]");
+
+ thelock->locked = 0;
+
+ /* wake up someone (anyone, if any) waiting on the lock */
+ status = pthread_cond_signal( &thelock->lock_released );
+ CHECK_STATUS_PTHREAD("pthread_cond_signal");
+
+ status = pthread_mutex_unlock( &thelock->mut );
+ CHECK_STATUS_PTHREAD("pthread_mutex_unlock[3]");
+}
+
+#endif /* USE_SEMAPHORES */
+
+int
+_PyThread_at_fork_reinit(PyThread_type_lock *lock)
+{
+ PyThread_type_lock new_lock = PyThread_allocate_lock();
+ if (new_lock == NULL) {
+ return -1;
+ }
+
+ /* bpo-6721, bpo-40089: The old lock can be in an inconsistent state.
+ fork() can be called in the middle of an operation on the lock done by
+ another thread. So don't call PyThread_free_lock(*lock).
+
+ Leak memory on purpose. Don't release the memory either since the
+ address of a mutex is relevant. Putting two mutexes at the same address
+ can lead to problems. */
+
+ *lock = new_lock;
+ return 0;
+}
+
+int
+PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
+{
+ return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0);
+}
+
+/* set the thread stack size.
+ * Return 0 if size is valid, -1 if size is invalid,
+ * -2 if setting stack size is not supported.
+ */
+static int
+_pythread_pthread_set_stacksize(size_t size)
+{
+#if defined(THREAD_STACK_SIZE)
+ pthread_attr_t attrs;
+ size_t tss_min;
+ int rc = 0;
+#endif
+
+ /* set to default */
+ if (size == 0) {
+ _PyInterpreterState_GET()->pythread_stacksize = 0;
+ return 0;
+ }
+
+#if defined(THREAD_STACK_SIZE)
+#if defined(PTHREAD_STACK_MIN)
+ tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
+ : THREAD_STACK_MIN;
+#else
+ tss_min = THREAD_STACK_MIN;
+#endif
+ if (size >= tss_min) {
+ /* validate stack size by setting thread attribute */
+ if (pthread_attr_init(&attrs) == 0) {
+ rc = pthread_attr_setstacksize(&attrs, size);
+ pthread_attr_destroy(&attrs);
+ if (rc == 0) {
+ _PyInterpreterState_GET()->pythread_stacksize = size;
+ return 0;
+ }
+ }
+ }
+ return -1;
+#else
+ return -2;
+#endif
+}
+
+#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
+
+
+/* Thread Local Storage (TLS) API
+
+ This API is DEPRECATED since Python 3.7. See PEP 539 for details.
+*/
+
+/* Issue #25658: On platforms where native TLS key is defined in a way that
+ cannot be safely cast to int, PyThread_create_key returns immediately a
+ failure status and other TLS functions all are no-ops. This indicates
+ clearly that the old API is not supported on platforms where it cannot be
+ used reliably, and that no effort will be made to add such support.
+
+ Note: PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT will be unnecessary after
+ removing this API.
+*/
+
+int
+PyThread_create_key(void)
+{
+#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
+ pthread_key_t key;
+ int fail = pthread_key_create(&key, NULL);
+ if (fail)
+ return -1;
+ if (key > INT_MAX) {
+ /* Issue #22206: handle integer overflow */
+ pthread_key_delete(key);
+ errno = ENOMEM;
+ return -1;
+ }
+ return (int)key;
+#else
+ return -1; /* never return valid key value. */
+#endif
+}
+
+void
+PyThread_delete_key(int key)
+{
+#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
+ pthread_key_delete(key);
+#endif
+}
+
+void
+PyThread_delete_key_value(int key)
+{
+#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
+ pthread_setspecific(key, NULL);
+#endif
+}
+
+int
+PyThread_set_key_value(int key, void *value)
+{
+#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
+ int fail = pthread_setspecific(key, value);
+ return fail ? -1 : 0;
+#else
+ return -1;
+#endif
+}
+
+void *
+PyThread_get_key_value(int key)
+{
+#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
+ return pthread_getspecific(key);
+#else
+ return NULL;
+#endif
+}
+
+
+void
+PyThread_ReInitTLS(void)
+{
+}
+
+
+/* Thread Specific Storage (TSS) API
+
+ Platform-specific components of TSS API implementation.
+*/
+
+int
+PyThread_tss_create(Py_tss_t *key)
+{
+ assert(key != NULL);
+ /* If the key has been created, function is silently skipped. */
+ if (key->_is_initialized) {
+ return 0;
+ }
+
+ int fail = pthread_key_create(&(key->_key), NULL);
+ if (fail) {
+ return -1;
+ }
+ key->_is_initialized = 1;
+ return 0;
+}
+
+void
+PyThread_tss_delete(Py_tss_t *key)
+{
+ assert(key != NULL);
+ /* If the key has not been created, function is silently skipped. */
+ if (!key->_is_initialized) {
+ return;
+ }
+
+ pthread_key_delete(key->_key);
+ /* pthread has not provided the defined invalid value for the key. */
+ key->_is_initialized = 0;
+}
+
+int
+PyThread_tss_set(Py_tss_t *key, void *value)
+{
+ assert(key != NULL);
+ int fail = pthread_setspecific(key->_key, value);
+ return fail ? -1 : 0;
+}
+
+void *
+PyThread_tss_get(Py_tss_t *key)
+{
+ assert(key != NULL);
+ return pthread_getspecific(key->_key);
+}
diff --git a/contrib/tools/python3/src/Python/traceback.c b/contrib/tools/python3/src/Python/traceback.c
new file mode 100644
index 00000000000..23d0e38e737
--- /dev/null
+++ b/contrib/tools/python3/src/Python/traceback.c
@@ -0,0 +1,951 @@
+
+/* Traceback implementation */
+
+#include "Python.h"
+
+#include "code.h"
+#include "frameobject.h" // PyFrame_GetBack()
+#include "structmember.h" // PyMemberDef
+#include "osdefs.h" // SEP
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#define OFF(x) offsetof(PyTracebackObject, x)
+
+#define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str))
+#define MAX_STRING_LENGTH 500
+#define MAX_FRAME_DEPTH 100
+#define MAX_NTHREADS 100
+
+/* Function from Parser/tokenizer.c */
+extern char * PyTokenizer_FindEncodingFilename(int, PyObject *);
+
+_Py_IDENTIFIER(TextIOWrapper);
+_Py_IDENTIFIER(close);
+_Py_IDENTIFIER(open);
+_Py_IDENTIFIER(path);
+
+/*[clinic input]
+class TracebackType "PyTracebackObject *" "&PyTraceback_Type"
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=928fa06c10151120]*/
+
+#include "clinic/traceback.c.h"
+
+static PyObject *
+tb_create_raw(PyTracebackObject *next, PyFrameObject *frame, int lasti,
+ int lineno)
+{
+ PyTracebackObject *tb;
+ if ((next != NULL && !PyTraceBack_Check(next)) ||
+ frame == NULL || !PyFrame_Check(frame)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ tb = PyObject_GC_New(PyTracebackObject, &PyTraceBack_Type);
+ if (tb != NULL) {
+ Py_XINCREF(next);
+ tb->tb_next = next;
+ Py_XINCREF(frame);
+ tb->tb_frame = frame;
+ tb->tb_lasti = lasti;
+ tb->tb_lineno = lineno;
+ PyObject_GC_Track(tb);
+ }
+ return (PyObject *)tb;
+}
+
+/*[clinic input]
+@classmethod
+TracebackType.__new__ as tb_new
+
+ tb_next: object
+ tb_frame: object(type='PyFrameObject *', subclass_of='&PyFrame_Type')
+ tb_lasti: int
+ tb_lineno: int
+
+Create a new traceback object.
+[clinic start generated code]*/
+
+static PyObject *
+tb_new_impl(PyTypeObject *type, PyObject *tb_next, PyFrameObject *tb_frame,
+ int tb_lasti, int tb_lineno)
+/*[clinic end generated code: output=fa077debd72d861a input=01cbe8ec8783fca7]*/
+{
+ if (tb_next == Py_None) {
+ tb_next = NULL;
+ } else if (!PyTraceBack_Check(tb_next)) {
+ return PyErr_Format(PyExc_TypeError,
+ "expected traceback object or None, got '%s'",
+ Py_TYPE(tb_next)->tp_name);
+ }
+
+ return tb_create_raw((PyTracebackObject *)tb_next, tb_frame, tb_lasti,
+ tb_lineno);
+}
+
+static PyObject *
+tb_dir(PyTracebackObject *self, PyObject *Py_UNUSED(ignored))
+{
+ return Py_BuildValue("[ssss]", "tb_frame", "tb_next",
+ "tb_lasti", "tb_lineno");
+}
+
+static PyObject *
+tb_next_get(PyTracebackObject *self, void *Py_UNUSED(_))
+{
+ PyObject* ret = (PyObject*)self->tb_next;
+ if (!ret) {
+ ret = Py_None;
+ }
+ Py_INCREF(ret);
+ return ret;
+}
+
+static int
+tb_next_set(PyTracebackObject *self, PyObject *new_next, void *Py_UNUSED(_))
+{
+ if (!new_next) {
+ PyErr_Format(PyExc_TypeError, "can't delete tb_next attribute");
+ return -1;
+ }
+
+ /* We accept None or a traceback object, and map None -> NULL (inverse of
+ tb_next_get) */
+ if (new_next == Py_None) {
+ new_next = NULL;
+ } else if (!PyTraceBack_Check(new_next)) {
+ PyErr_Format(PyExc_TypeError,
+ "expected traceback object, got '%s'",
+ Py_TYPE(new_next)->tp_name);
+ return -1;
+ }
+
+ /* Check for loops */
+ PyTracebackObject *cursor = (PyTracebackObject *)new_next;
+ while (cursor) {
+ if (cursor == self) {
+ PyErr_Format(PyExc_ValueError, "traceback loop detected");
+ return -1;
+ }
+ cursor = cursor->tb_next;
+ }
+
+ PyObject *old_next = (PyObject*)self->tb_next;
+ Py_XINCREF(new_next);
+ self->tb_next = (PyTracebackObject *)new_next;
+ Py_XDECREF(old_next);
+
+ return 0;
+}
+
+
+static PyMethodDef tb_methods[] = {
+ {"__dir__", (PyCFunction)tb_dir, METH_NOARGS},
+ {NULL, NULL, 0, NULL},
+};
+
+static PyMemberDef tb_memberlist[] = {
+ {"tb_frame", T_OBJECT, OFF(tb_frame), READONLY|READ_RESTRICTED},
+ {"tb_lasti", T_INT, OFF(tb_lasti), READONLY},
+ {"tb_lineno", T_INT, OFF(tb_lineno), READONLY},
+ {NULL} /* Sentinel */
+};
+
+static PyGetSetDef tb_getsetters[] = {
+ {"tb_next", (getter)tb_next_get, (setter)tb_next_set, NULL, NULL},
+ {NULL} /* Sentinel */
+};
+
+static void
+tb_dealloc(PyTracebackObject *tb)
+{
+ PyObject_GC_UnTrack(tb);
+ Py_TRASHCAN_BEGIN(tb, tb_dealloc)
+ Py_XDECREF(tb->tb_next);
+ Py_XDECREF(tb->tb_frame);
+ PyObject_GC_Del(tb);
+ Py_TRASHCAN_END
+}
+
+static int
+tb_traverse(PyTracebackObject *tb, visitproc visit, void *arg)
+{
+ Py_VISIT(tb->tb_next);
+ Py_VISIT(tb->tb_frame);
+ return 0;
+}
+
+static int
+tb_clear(PyTracebackObject *tb)
+{
+ Py_CLEAR(tb->tb_next);
+ Py_CLEAR(tb->tb_frame);
+ return 0;
+}
+
+PyTypeObject PyTraceBack_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "traceback",
+ sizeof(PyTracebackObject),
+ 0,
+ (destructor)tb_dealloc, /*tp_dealloc*/
+ 0, /*tp_vectorcall_offset*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_as_async*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ tb_new__doc__, /* tp_doc */
+ (traverseproc)tb_traverse, /* tp_traverse */
+ (inquiry)tb_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ tb_methods, /* tp_methods */
+ tb_memberlist, /* tp_members */
+ tb_getsetters, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ tb_new, /* tp_new */
+};
+
+
+PyObject*
+_PyTraceBack_FromFrame(PyObject *tb_next, PyFrameObject *frame)
+{
+ assert(tb_next == NULL || PyTraceBack_Check(tb_next));
+ assert(frame != NULL);
+
+ return tb_create_raw((PyTracebackObject *)tb_next, frame, frame->f_lasti,
+ PyFrame_GetLineNumber(frame));
+}
+
+
+int
+PyTraceBack_Here(PyFrameObject *frame)
+{
+ PyObject *exc, *val, *tb, *newtb;
+ PyErr_Fetch(&exc, &val, &tb);
+ newtb = _PyTraceBack_FromFrame(tb, frame);
+ if (newtb == NULL) {
+ _PyErr_ChainExceptions(exc, val, tb);
+ return -1;
+ }
+ PyErr_Restore(exc, val, newtb);
+ Py_XDECREF(tb);
+ return 0;
+}
+
+/* Insert a frame into the traceback for (funcname, filename, lineno). */
+void _PyTraceback_Add(const char *funcname, const char *filename, int lineno)
+{
+ PyObject *globals;
+ PyCodeObject *code;
+ PyFrameObject *frame;
+ PyObject *exc, *val, *tb;
+
+ /* Save and clear the current exception. Python functions must not be
+ called with an exception set. Calling Python functions happens when
+ the codec of the filesystem encoding is implemented in pure Python. */
+ PyErr_Fetch(&exc, &val, &tb);
+
+ globals = PyDict_New();
+ if (!globals)
+ goto error;
+ code = PyCode_NewEmpty(filename, funcname, lineno);
+ if (!code) {
+ Py_DECREF(globals);
+ goto error;
+ }
+ frame = PyFrame_New(PyThreadState_Get(), code, globals, NULL);
+ Py_DECREF(globals);
+ Py_DECREF(code);
+ if (!frame)
+ goto error;
+ frame->f_lineno = lineno;
+
+ PyErr_Restore(exc, val, tb);
+ PyTraceBack_Here(frame);
+ Py_DECREF(frame);
+ return;
+
+error:
+ _PyErr_ChainExceptions(exc, val, tb);
+}
+
+static PyObject *
+_Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *io)
+{
+ Py_ssize_t i;
+ PyObject *binary;
+ PyObject *v;
+ Py_ssize_t npath;
+ size_t taillen;
+ PyObject *syspath;
+ PyObject *path;
+ const char* tail;
+ PyObject *filebytes;
+ const char* filepath;
+ Py_ssize_t len;
+ PyObject* result;
+
+ filebytes = PyUnicode_EncodeFSDefault(filename);
+ if (filebytes == NULL) {
+ PyErr_Clear();
+ return NULL;
+ }
+ filepath = PyBytes_AS_STRING(filebytes);
+
+ /* Search tail of filename in sys.path before giving up */
+ tail = strrchr(filepath, SEP);
+ if (tail == NULL)
+ tail = filepath;
+ else
+ tail++;
+ taillen = strlen(tail);
+
+ syspath = _PySys_GetObjectId(&PyId_path);
+ if (syspath == NULL || !PyList_Check(syspath))
+ goto error;
+ npath = PyList_Size(syspath);
+
+ for (i = 0; i < npath; i++) {
+ v = PyList_GetItem(syspath, i);
+ if (v == NULL) {
+ PyErr_Clear();
+ break;
+ }
+ if (!PyUnicode_Check(v))
+ continue;
+ path = PyUnicode_EncodeFSDefault(v);
+ if (path == NULL) {
+ PyErr_Clear();
+ continue;
+ }
+ len = PyBytes_GET_SIZE(path);
+ if (len + 1 + (Py_ssize_t)taillen >= (Py_ssize_t)namelen - 1) {
+ Py_DECREF(path);
+ continue; /* Too long */
+ }
+ strcpy(namebuf, PyBytes_AS_STRING(path));
+ Py_DECREF(path);
+ if (strlen(namebuf) != (size_t)len)
+ continue; /* v contains '\0' */
+ if (len > 0 && namebuf[len-1] != SEP)
+ namebuf[len++] = SEP;
+ strcpy(namebuf+len, tail);
+
+ binary = _PyObject_CallMethodId(io, &PyId_open, "ss", namebuf, "rb");
+ if (binary != NULL) {
+ result = binary;
+ goto finally;
+ }
+ PyErr_Clear();
+ }
+ goto error;
+
+error:
+ result = NULL;
+finally:
+ Py_DECREF(filebytes);
+ return result;
+}
+
+int
+_Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent)
+{
+ int err = 0;
+ int fd;
+ int i;
+ char *found_encoding;
+ const char *encoding;
+ PyObject *io;
+ PyObject *binary;
+ PyObject *fob = NULL;
+ PyObject *lineobj = NULL;
+ PyObject *res;
+ char buf[MAXPATHLEN+1];
+ int kind;
+ const void *data;
+
+ /* open the file */
+ if (filename == NULL)
+ return 0;
+
+ io = PyImport_ImportModuleNoBlock("io");
+ if (io == NULL)
+ return -1;
+ binary = _PyObject_CallMethodId(io, &PyId_open, "Os", filename, "rb");
+
+ if (binary == NULL) {
+ PyErr_Clear();
+
+ binary = _Py_FindSourceFile(filename, buf, sizeof(buf), io);
+ if (binary == NULL) {
+ Py_DECREF(io);
+ return -1;
+ }
+ }
+
+ /* use the right encoding to decode the file as unicode */
+ fd = PyObject_AsFileDescriptor(binary);
+ if (fd < 0) {
+ Py_DECREF(io);
+ Py_DECREF(binary);
+ return 0;
+ }
+ found_encoding = PyTokenizer_FindEncodingFilename(fd, filename);
+ if (found_encoding == NULL)
+ PyErr_Clear();
+ encoding = (found_encoding != NULL) ? found_encoding : "utf-8";
+ /* Reset position */
+ if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
+ Py_DECREF(io);
+ Py_DECREF(binary);
+ PyMem_FREE(found_encoding);
+ return 0;
+ }
+ fob = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "Os", binary, encoding);
+ Py_DECREF(io);
+ PyMem_FREE(found_encoding);
+
+ if (fob == NULL) {
+ PyErr_Clear();
+
+ res = _PyObject_CallMethodIdNoArgs(binary, &PyId_close);
+ Py_DECREF(binary);
+ if (res)
+ Py_DECREF(res);
+ else
+ PyErr_Clear();
+ return 0;
+ }
+ Py_DECREF(binary);
+
+ /* get the line number lineno */
+ for (i = 0; i < lineno; i++) {
+ Py_XDECREF(lineobj);
+ lineobj = PyFile_GetLine(fob, -1);
+ if (!lineobj) {
+ PyErr_Clear();
+ err = -1;
+ break;
+ }
+ }
+ res = _PyObject_CallMethodIdNoArgs(fob, &PyId_close);
+ if (res)
+ Py_DECREF(res);
+ else
+ PyErr_Clear();
+ Py_DECREF(fob);
+ if (!lineobj || !PyUnicode_Check(lineobj)) {
+ Py_XDECREF(lineobj);
+ return err;
+ }
+
+ /* remove the indentation of the line */
+ kind = PyUnicode_KIND(lineobj);
+ data = PyUnicode_DATA(lineobj);
+ for (i=0; i < PyUnicode_GET_LENGTH(lineobj); i++) {
+ Py_UCS4 ch = PyUnicode_READ(kind, data, i);
+ if (ch != ' ' && ch != '\t' && ch != '\014')
+ break;
+ }
+ if (i) {
+ PyObject *truncated;
+ truncated = PyUnicode_Substring(lineobj, i, PyUnicode_GET_LENGTH(lineobj));
+ if (truncated) {
+ Py_DECREF(lineobj);
+ lineobj = truncated;
+ } else {
+ PyErr_Clear();
+ }
+ }
+
+ /* Write some spaces before the line */
+ strcpy(buf, " ");
+ assert (strlen(buf) == 10);
+ while (indent > 0) {
+ if (indent < 10)
+ buf[indent] = '\0';
+ err = PyFile_WriteString(buf, f);
+ if (err != 0)
+ break;
+ indent -= 10;
+ }
+
+ /* finally display the line */
+ if (err == 0)
+ err = PyFile_WriteObject(lineobj, f, Py_PRINT_RAW);
+ Py_DECREF(lineobj);
+ if (err == 0)
+ err = PyFile_WriteString("\n", f);
+ return err;
+}
+
+static int
+tb_displayline(PyObject *f, PyObject *filename, int lineno, PyObject *name)
+{
+ int err;
+ PyObject *line;
+
+ if (filename == NULL || name == NULL)
+ return -1;
+ line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n",
+ filename, lineno, name);
+ if (line == NULL)
+ return -1;
+ err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
+ Py_DECREF(line);
+ if (err != 0)
+ return err;
+ /* ignore errors since we can't report them, can we? */
+ if (_Py_DisplaySourceLine(f, filename, lineno, 4))
+ PyErr_Clear();
+ return err;
+}
+
+static const int TB_RECURSIVE_CUTOFF = 3; // Also hardcoded in traceback.py.
+
+static int
+tb_print_line_repeated(PyObject *f, long cnt)
+{
+ cnt -= TB_RECURSIVE_CUTOFF;
+ PyObject *line = PyUnicode_FromFormat(
+ (cnt > 1)
+ ? " [Previous line repeated %ld more times]\n"
+ : " [Previous line repeated %ld more time]\n",
+ cnt);
+ if (line == NULL) {
+ return -1;
+ }
+ int err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
+ Py_DECREF(line);
+ return err;
+}
+
+static int
+tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit)
+{
+ int err = 0;
+ Py_ssize_t depth = 0;
+ PyObject *last_file = NULL;
+ int last_line = -1;
+ PyObject *last_name = NULL;
+ long cnt = 0;
+ PyTracebackObject *tb1 = tb;
+ while (tb1 != NULL) {
+ depth++;
+ tb1 = tb1->tb_next;
+ }
+ while (tb != NULL && depth > limit) {
+ depth--;
+ tb = tb->tb_next;
+ }
+ while (tb != NULL && err == 0) {
+ PyCodeObject *code = PyFrame_GetCode(tb->tb_frame);
+ if (last_file == NULL ||
+ code->co_filename != last_file ||
+ last_line == -1 || tb->tb_lineno != last_line ||
+ last_name == NULL || code->co_name != last_name) {
+ if (cnt > TB_RECURSIVE_CUTOFF) {
+ err = tb_print_line_repeated(f, cnt);
+ }
+ last_file = code->co_filename;
+ last_line = tb->tb_lineno;
+ last_name = code->co_name;
+ cnt = 0;
+ }
+ cnt++;
+ if (err == 0 && cnt <= TB_RECURSIVE_CUTOFF) {
+ err = tb_displayline(f, code->co_filename, tb->tb_lineno,
+ code->co_name);
+ if (err == 0) {
+ err = PyErr_CheckSignals();
+ }
+ }
+ Py_DECREF(code);
+ tb = tb->tb_next;
+ }
+ if (err == 0 && cnt > TB_RECURSIVE_CUTOFF) {
+ err = tb_print_line_repeated(f, cnt);
+ }
+ return err;
+}
+
+#define PyTraceBack_LIMIT 1000
+
+int
+PyTraceBack_Print(PyObject *v, PyObject *f)
+{
+ int err;
+ PyObject *limitv;
+ long limit = PyTraceBack_LIMIT;
+
+ if (v == NULL)
+ return 0;
+ if (!PyTraceBack_Check(v)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ limitv = PySys_GetObject("tracebacklimit");
+ if (limitv && PyLong_Check(limitv)) {
+ int overflow;
+ limit = PyLong_AsLongAndOverflow(limitv, &overflow);
+ if (overflow > 0) {
+ limit = LONG_MAX;
+ }
+ else if (limit <= 0) {
+ return 0;
+ }
+ }
+ err = PyFile_WriteString("Traceback (most recent call last):\n", f);
+ if (!err)
+ err = tb_printinternal((PyTracebackObject *)v, f, limit);
+ return err;
+}
+
+/* Format an integer in range [0; 0xffffffff] to decimal and write it
+ into the file fd.
+
+ This function is signal safe. */
+
+void
+_Py_DumpDecimal(int fd, unsigned long value)
+{
+ /* maximum number of characters required for output of %lld or %p.
+ We need at most ceil(log10(256)*SIZEOF_LONG_LONG) digits,
+ plus 1 for the null byte. 53/22 is an upper bound for log10(256). */
+ char buffer[1 + (sizeof(unsigned long)*53-1) / 22 + 1];
+ char *ptr, *end;
+
+ end = &buffer[Py_ARRAY_LENGTH(buffer) - 1];
+ ptr = end;
+ *ptr = '\0';
+ do {
+ --ptr;
+ assert(ptr >= buffer);
+ *ptr = '0' + (value % 10);
+ value /= 10;
+ } while (value);
+
+ _Py_write_noraise(fd, ptr, end - ptr);
+}
+
+/* Format an integer in range [0; 0xffffffff] to hexadecimal of 'width' digits,
+ and write it into the file fd.
+
+ This function is signal safe. */
+
+void
+_Py_DumpHexadecimal(int fd, unsigned long value, Py_ssize_t width)
+{
+ char buffer[sizeof(unsigned long) * 2 + 1], *ptr, *end;
+ const Py_ssize_t size = Py_ARRAY_LENGTH(buffer) - 1;
+
+ if (width > size)
+ width = size;
+ /* it's ok if width is negative */
+
+ end = &buffer[size];
+ ptr = end;
+ *ptr = '\0';
+ do {
+ --ptr;
+ assert(ptr >= buffer);
+ *ptr = Py_hexdigits[value & 15];
+ value >>= 4;
+ } while ((end - ptr) < width || value);
+
+ _Py_write_noraise(fd, ptr, end - ptr);
+}
+
+void
+_Py_DumpASCII(int fd, PyObject *text)
+{
+ PyASCIIObject *ascii = (PyASCIIObject *)text;
+ Py_ssize_t i, size;
+ int truncated;
+ int kind;
+ void *data = NULL;
+ wchar_t *wstr = NULL;
+ Py_UCS4 ch;
+
+ if (!PyUnicode_Check(text))
+ return;
+
+ size = ascii->length;
+ kind = ascii->state.kind;
+ if (kind == PyUnicode_WCHAR_KIND) {
+ wstr = ((PyASCIIObject *)text)->wstr;
+ if (wstr == NULL)
+ return;
+ size = ((PyCompactUnicodeObject *)text)->wstr_length;
+ }
+ else if (ascii->state.compact) {
+ if (ascii->state.ascii)
+ data = ((PyASCIIObject*)text) + 1;
+ else
+ data = ((PyCompactUnicodeObject*)text) + 1;
+ }
+ else {
+ data = ((PyUnicodeObject *)text)->data.any;
+ if (data == NULL)
+ return;
+ }
+
+ if (MAX_STRING_LENGTH < size) {
+ size = MAX_STRING_LENGTH;
+ truncated = 1;
+ }
+ else {
+ truncated = 0;
+ }
+
+ // Is an ASCII string?
+ if (ascii->state.ascii) {
+ assert(kind == PyUnicode_1BYTE_KIND);
+ char *str = data;
+
+ int need_escape = 0;
+ for (i=0; i < size; i++) {
+ ch = str[i];
+ if (!(' ' <= ch && ch <= 126)) {
+ need_escape = 1;
+ break;
+ }
+ }
+ if (!need_escape) {
+ // The string can be written with a single write() syscall
+ _Py_write_noraise(fd, str, size);
+ goto done;
+ }
+ }
+
+ for (i=0; i < size; i++) {
+ if (kind != PyUnicode_WCHAR_KIND)
+ ch = PyUnicode_READ(kind, data, i);
+ else
+ ch = wstr[i];
+ if (' ' <= ch && ch <= 126) {
+ /* printable ASCII character */
+ char c = (char)ch;
+ _Py_write_noraise(fd, &c, 1);
+ }
+ else if (ch <= 0xff) {
+ PUTS(fd, "\\x");
+ _Py_DumpHexadecimal(fd, ch, 2);
+ }
+ else if (ch <= 0xffff) {
+ PUTS(fd, "\\u");
+ _Py_DumpHexadecimal(fd, ch, 4);
+ }
+ else {
+ PUTS(fd, "\\U");
+ _Py_DumpHexadecimal(fd, ch, 8);
+ }
+ }
+
+done:
+ if (truncated) {
+ PUTS(fd, "...");
+ }
+}
+
+/* Write a frame into the file fd: "File "xxx", line xxx in xxx".
+
+ This function is signal safe. */
+
+static void
+dump_frame(int fd, PyFrameObject *frame)
+{
+ PyCodeObject *code = PyFrame_GetCode(frame);
+ PUTS(fd, " File ");
+ if (code->co_filename != NULL
+ && PyUnicode_Check(code->co_filename))
+ {
+ PUTS(fd, "\"");
+ _Py_DumpASCII(fd, code->co_filename);
+ PUTS(fd, "\"");
+ } else {
+ PUTS(fd, "???");
+ }
+
+ /* PyFrame_GetLineNumber() was introduced in Python 2.7.0 and 3.2.0 */
+ int lineno = PyCode_Addr2Line(code, frame->f_lasti);
+ PUTS(fd, ", line ");
+ if (lineno >= 0) {
+ _Py_DumpDecimal(fd, (unsigned long)lineno);
+ }
+ else {
+ PUTS(fd, "???");
+ }
+ PUTS(fd, " in ");
+
+ if (code->co_name != NULL
+ && PyUnicode_Check(code->co_name)) {
+ _Py_DumpASCII(fd, code->co_name);
+ }
+ else {
+ PUTS(fd, "???");
+ }
+
+ PUTS(fd, "\n");
+ Py_DECREF(code);
+}
+
+static void
+dump_traceback(int fd, PyThreadState *tstate, int write_header)
+{
+ PyFrameObject *frame;
+ unsigned int depth;
+
+ if (write_header) {
+ PUTS(fd, "Stack (most recent call first):\n");
+ }
+
+ // Use a borrowed reference. Avoid Py_INCREF/Py_DECREF, since this function
+ // can be called in a signal handler by the faulthandler module which must
+ // not modify Python objects.
+ frame = tstate->frame;
+ if (frame == NULL) {
+ PUTS(fd, "<no Python frame>\n");
+ return;
+ }
+
+ depth = 0;
+ while (1) {
+ if (MAX_FRAME_DEPTH <= depth) {
+ PUTS(fd, " ...\n");
+ break;
+ }
+ if (!PyFrame_Check(frame)) {
+ break;
+ }
+ dump_frame(fd, frame);
+ PyFrameObject *back = frame->f_back;
+
+ if (back == NULL) {
+ break;
+ }
+ frame = back;
+ depth++;
+ }
+}
+
+/* Dump the traceback of a Python thread into fd. Use write() to write the
+ traceback and retry if write() is interrupted by a signal (failed with
+ EINTR), but don't call the Python signal handler.
+
+ The caller is responsible to call PyErr_CheckSignals() to call Python signal
+ handlers if signals were received. */
+void
+_Py_DumpTraceback(int fd, PyThreadState *tstate)
+{
+ dump_traceback(fd, tstate, 1);
+}
+
+/* Write the thread identifier into the file 'fd': "Current thread 0xHHHH:\" if
+ is_current is true, "Thread 0xHHHH:\n" otherwise.
+
+ This function is signal safe. */
+
+static void
+write_thread_id(int fd, PyThreadState *tstate, int is_current)
+{
+ if (is_current)
+ PUTS(fd, "Current thread 0x");
+ else
+ PUTS(fd, "Thread 0x");
+ _Py_DumpHexadecimal(fd,
+ tstate->thread_id,
+ sizeof(unsigned long) * 2);
+ PUTS(fd, " (most recent call first):\n");
+}
+
+/* Dump the traceback of all Python threads into fd. Use write() to write the
+ traceback and retry if write() is interrupted by a signal (failed with
+ EINTR), but don't call the Python signal handler.
+
+ The caller is responsible to call PyErr_CheckSignals() to call Python signal
+ handlers if signals were received. */
+const char*
+_Py_DumpTracebackThreads(int fd, PyInterpreterState *interp,
+ PyThreadState *current_tstate)
+{
+ PyThreadState *tstate;
+ unsigned int nthreads;
+
+ if (current_tstate == NULL) {
+ /* _Py_DumpTracebackThreads() is called from signal handlers by
+ faulthandler.
+
+ SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals
+ and are thus delivered to the thread that caused the fault. Get the
+ Python thread state of the current thread.
+
+ PyThreadState_Get() doesn't give the state of the thread that caused
+ the fault if the thread released the GIL, and so
+ _PyThreadState_GET() cannot be used. Read the thread specific
+ storage (TSS) instead: call PyGILState_GetThisThreadState(). */
+ current_tstate = PyGILState_GetThisThreadState();
+ }
+
+ if (interp == NULL) {
+ if (current_tstate == NULL) {
+ interp = _PyGILState_GetInterpreterStateUnsafe();
+ if (interp == NULL) {
+ /* We need the interpreter state to get Python threads */
+ return "unable to get the interpreter state";
+ }
+ }
+ else {
+ interp = current_tstate->interp;
+ }
+ }
+ assert(interp != NULL);
+
+ /* Get the current interpreter from the current thread */
+ tstate = PyInterpreterState_ThreadHead(interp);
+ if (tstate == NULL)
+ return "unable to get the thread head state";
+
+ /* Dump the traceback of each thread */
+ tstate = PyInterpreterState_ThreadHead(interp);
+ nthreads = 0;
+ _Py_BEGIN_SUPPRESS_IPH
+ do
+ {
+ if (nthreads != 0)
+ PUTS(fd, "\n");
+ if (nthreads >= MAX_NTHREADS) {
+ PUTS(fd, "...\n");
+ break;
+ }
+ write_thread_id(fd, tstate, tstate == current_tstate);
+ dump_traceback(fd, tstate, 0);
+ tstate = PyThreadState_Next(tstate);
+ nthreads++;
+ } while (tstate != NULL);
+ _Py_END_SUPPRESS_IPH
+
+ return NULL;
+}
+
diff --git a/contrib/tools/python3/src/Python/wordcode_helpers.h b/contrib/tools/python3/src/Python/wordcode_helpers.h
new file mode 100644
index 00000000000..c8f7a0f41f9
--- /dev/null
+++ b/contrib/tools/python3/src/Python/wordcode_helpers.h
@@ -0,0 +1,44 @@
+/* This file contains code shared by the compiler and the peephole
+ optimizer.
+ */
+
+#ifdef WORDS_BIGENDIAN
+# define PACKOPARG(opcode, oparg) ((_Py_CODEUNIT)(((opcode) << 8) | (oparg)))
+#else
+# define PACKOPARG(opcode, oparg) ((_Py_CODEUNIT)(((oparg) << 8) | (opcode)))
+#endif
+
+/* Minimum number of code units necessary to encode instruction with
+ EXTENDED_ARGs */
+static int
+instrsize(unsigned int oparg)
+{
+ return oparg <= 0xff ? 1 :
+ oparg <= 0xffff ? 2 :
+ oparg <= 0xffffff ? 3 :
+ 4;
+}
+
+/* Spits out op/oparg pair using ilen bytes. codestr should be pointed at the
+ desired location of the first EXTENDED_ARG */
+static void
+write_op_arg(_Py_CODEUNIT *codestr, unsigned char opcode,
+ unsigned int oparg, int ilen)
+{
+ switch (ilen) {
+ case 4:
+ *codestr++ = PACKOPARG(EXTENDED_ARG, (oparg >> 24) & 0xff);
+ /* fall through */
+ case 3:
+ *codestr++ = PACKOPARG(EXTENDED_ARG, (oparg >> 16) & 0xff);
+ /* fall through */
+ case 2:
+ *codestr++ = PACKOPARG(EXTENDED_ARG, (oparg >> 8) & 0xff);
+ /* fall through */
+ case 1:
+ *codestr++ = PACKOPARG(opcode, oparg & 0xff);
+ break;
+ default:
+ Py_UNREACHABLE();
+ }
+}