aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Python
diff options
context:
space:
mode:
Diffstat (limited to 'Python')
-rw-r--r--Python/Python-ast.c349
-rw-r--r--Python/ast.c13
-rw-r--r--Python/ast_opt.c7
-rw-r--r--Python/ast_unparse.c201
-rw-r--r--Python/bltinmodule.c2
-rw-r--r--Python/bytecodes.c298
-rw-r--r--Python/ceval.c8
-rw-r--r--Python/codecs.c18
-rw-r--r--Python/codegen.c110
-rw-r--r--Python/executor_cases.c.h83
-rw-r--r--Python/gc.c5
-rw-r--r--Python/gc_free_threading.c5
-rw-r--r--Python/generated_cases.c.h113
-rw-r--r--Python/hamt.c6
-rw-r--r--Python/instruction_sequence.c2
-rw-r--r--Python/intrinsics.c1
-rw-r--r--Python/jit.c2
-rw-r--r--Python/opcode_targets.h16
-rw-r--r--Python/optimizer_cases.c.h18
-rw-r--r--Python/pylifecycle.c10
-rw-r--r--Python/pystate.c5
-rw-r--r--Python/symtable.c8
-rw-r--r--Python/traceback.c2
23 files changed, 1046 insertions, 236 deletions
diff --git a/Python/Python-ast.c b/Python/Python-ast.c
index 98dcdc4ed0b..94d9a76d283 100644
--- a/Python/Python-ast.c
+++ b/Python/Python-ast.c
@@ -92,6 +92,7 @@ void _PyAST_Fini(PyInterpreterState *interp)
Py_CLEAR(state->In_singleton);
Py_CLEAR(state->In_type);
Py_CLEAR(state->Interactive_type);
+ Py_CLEAR(state->Interpolation_type);
Py_CLEAR(state->Invert_singleton);
Py_CLEAR(state->Invert_type);
Py_CLEAR(state->IsNot_singleton);
@@ -154,6 +155,7 @@ void _PyAST_Fini(PyInterpreterState *interp)
Py_CLEAR(state->Sub_singleton);
Py_CLEAR(state->Sub_type);
Py_CLEAR(state->Subscript_type);
+ Py_CLEAR(state->TemplateStr_type);
Py_CLEAR(state->TryStar_type);
Py_CLEAR(state->Try_type);
Py_CLEAR(state->Tuple_type);
@@ -259,6 +261,7 @@ void _PyAST_Fini(PyInterpreterState *interp)
Py_CLEAR(state->slice);
Py_CLEAR(state->step);
Py_CLEAR(state->stmt_type);
+ Py_CLEAR(state->str);
Py_CLEAR(state->subject);
Py_CLEAR(state->tag);
Py_CLEAR(state->target);
@@ -357,6 +360,7 @@ static int init_identifiers(struct ast_state *state)
if ((state->simple = PyUnicode_InternFromString("simple")) == NULL) return -1;
if ((state->slice = PyUnicode_InternFromString("slice")) == NULL) return -1;
if ((state->step = PyUnicode_InternFromString("step")) == NULL) return -1;
+ if ((state->str = PyUnicode_InternFromString("str")) == NULL) return -1;
if ((state->subject = PyUnicode_InternFromString("subject")) == NULL) return -1;
if ((state->tag = PyUnicode_InternFromString("tag")) == NULL) return -1;
if ((state->target = PyUnicode_InternFromString("target")) == NULL) return -1;
@@ -619,9 +623,18 @@ static const char * const FormattedValue_fields[]={
"conversion",
"format_spec",
};
+static const char * const Interpolation_fields[]={
+ "value",
+ "str",
+ "conversion",
+ "format_spec",
+};
static const char * const JoinedStr_fields[]={
"values",
};
+static const char * const TemplateStr_fields[]={
+ "values",
+};
static const char * const Constant_fields[]={
"value",
"kind",
@@ -3174,6 +3187,70 @@ add_ast_annotations(struct ast_state *state)
return 0;
}
Py_DECREF(FormattedValue_annotations);
+ PyObject *Interpolation_annotations = PyDict_New();
+ if (!Interpolation_annotations) return 0;
+ {
+ PyObject *type = state->expr_type;
+ Py_INCREF(type);
+ cond = PyDict_SetItemString(Interpolation_annotations, "value", type)
+ == 0;
+ Py_DECREF(type);
+ if (!cond) {
+ Py_DECREF(Interpolation_annotations);
+ return 0;
+ }
+ }
+ {
+ PyObject *type = (PyObject *)&PyBaseObject_Type;
+ Py_INCREF(type);
+ cond = PyDict_SetItemString(Interpolation_annotations, "str", type) ==
+ 0;
+ Py_DECREF(type);
+ if (!cond) {
+ Py_DECREF(Interpolation_annotations);
+ return 0;
+ }
+ }
+ {
+ PyObject *type = (PyObject *)&PyLong_Type;
+ Py_INCREF(type);
+ cond = PyDict_SetItemString(Interpolation_annotations, "conversion",
+ type) == 0;
+ Py_DECREF(type);
+ if (!cond) {
+ Py_DECREF(Interpolation_annotations);
+ return 0;
+ }
+ }
+ {
+ PyObject *type = state->expr_type;
+ type = _Py_union_type_or(type, Py_None);
+ cond = type != NULL;
+ if (!cond) {
+ Py_DECREF(Interpolation_annotations);
+ return 0;
+ }
+ cond = PyDict_SetItemString(Interpolation_annotations, "format_spec",
+ type) == 0;
+ Py_DECREF(type);
+ if (!cond) {
+ Py_DECREF(Interpolation_annotations);
+ return 0;
+ }
+ }
+ cond = PyObject_SetAttrString(state->Interpolation_type, "_field_types",
+ Interpolation_annotations) == 0;
+ if (!cond) {
+ Py_DECREF(Interpolation_annotations);
+ return 0;
+ }
+ cond = PyObject_SetAttrString(state->Interpolation_type, "__annotations__",
+ Interpolation_annotations) == 0;
+ if (!cond) {
+ Py_DECREF(Interpolation_annotations);
+ return 0;
+ }
+ Py_DECREF(Interpolation_annotations);
PyObject *JoinedStr_annotations = PyDict_New();
if (!JoinedStr_annotations) return 0;
{
@@ -3204,6 +3281,37 @@ add_ast_annotations(struct ast_state *state)
return 0;
}
Py_DECREF(JoinedStr_annotations);
+ PyObject *TemplateStr_annotations = PyDict_New();
+ if (!TemplateStr_annotations) return 0;
+ {
+ PyObject *type = state->expr_type;
+ type = Py_GenericAlias((PyObject *)&PyList_Type, type);
+ cond = type != NULL;
+ if (!cond) {
+ Py_DECREF(TemplateStr_annotations);
+ return 0;
+ }
+ cond = PyDict_SetItemString(TemplateStr_annotations, "values", type) ==
+ 0;
+ Py_DECREF(type);
+ if (!cond) {
+ Py_DECREF(TemplateStr_annotations);
+ return 0;
+ }
+ }
+ cond = PyObject_SetAttrString(state->TemplateStr_type, "_field_types",
+ TemplateStr_annotations) == 0;
+ if (!cond) {
+ Py_DECREF(TemplateStr_annotations);
+ return 0;
+ }
+ cond = PyObject_SetAttrString(state->TemplateStr_type, "__annotations__",
+ TemplateStr_annotations) == 0;
+ if (!cond) {
+ Py_DECREF(TemplateStr_annotations);
+ return 0;
+ }
+ Py_DECREF(TemplateStr_annotations);
PyObject *Constant_annotations = PyDict_New();
if (!Constant_annotations) return 0;
{
@@ -6266,7 +6374,9 @@ init_types(void *arg)
" | 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"
+ " | Interpolation(expr value, constant str, int conversion, expr? format_spec)\n"
" | JoinedStr(expr* values)\n"
+ " | TemplateStr(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"
@@ -6361,10 +6471,22 @@ init_types(void *arg)
if (PyObject_SetAttr(state->FormattedValue_type, state->format_spec,
Py_None) == -1)
return -1;
+ state->Interpolation_type = make_type(state, "Interpolation",
+ state->expr_type,
+ Interpolation_fields, 4,
+ "Interpolation(expr value, constant str, int conversion, expr? format_spec)");
+ if (!state->Interpolation_type) return -1;
+ if (PyObject_SetAttr(state->Interpolation_type, state->format_spec,
+ Py_None) == -1)
+ return -1;
state->JoinedStr_type = make_type(state, "JoinedStr", state->expr_type,
JoinedStr_fields, 1,
"JoinedStr(expr* values)");
if (!state->JoinedStr_type) return -1;
+ state->TemplateStr_type = make_type(state, "TemplateStr", state->expr_type,
+ TemplateStr_fields, 1,
+ "TemplateStr(expr* values)");
+ if (!state->TemplateStr_type) return -1;
state->Constant_type = make_type(state, "Constant", state->expr_type,
Constant_fields, 2,
"Constant(constant value, string? kind)");
@@ -8039,6 +8161,37 @@ _PyAST_FormattedValue(expr_ty value, int conversion, expr_ty format_spec, int
}
expr_ty
+_PyAST_Interpolation(expr_ty value, constant str, 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 Interpolation");
+ return NULL;
+ }
+ if (!str) {
+ PyErr_SetString(PyExc_ValueError,
+ "field 'str' is required for Interpolation");
+ return NULL;
+ }
+ p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = Interpolation_kind;
+ p->v.Interpolation.value = value;
+ p->v.Interpolation.str = str;
+ p->v.Interpolation.conversion = conversion;
+ p->v.Interpolation.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
_PyAST_JoinedStr(asdl_expr_seq * values, int lineno, int col_offset, int
end_lineno, int end_col_offset, PyArena *arena)
{
@@ -8056,6 +8209,23 @@ _PyAST_JoinedStr(asdl_expr_seq * values, int lineno, int col_offset, int
}
expr_ty
+_PyAST_TemplateStr(asdl_expr_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 = TemplateStr_kind;
+ p->v.TemplateStr.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
_PyAST_Constant(constant value, string kind, int lineno, int col_offset, int
end_lineno, int end_col_offset, PyArena *arena)
{
@@ -9674,6 +9844,31 @@ ast2obj_expr(struct ast_state *state, void* _o)
goto failed;
Py_DECREF(value);
break;
+ case Interpolation_kind:
+ tp = (PyTypeObject *)state->Interpolation_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(state, o->v.Interpolation.value);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->value, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_constant(state, o->v.Interpolation.str);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->str, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_int(state, o->v.Interpolation.conversion);
+ if (!value) goto failed;
+ if (PyObject_SetAttr(result, state->conversion, value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(state, o->v.Interpolation.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);
@@ -9685,6 +9880,17 @@ ast2obj_expr(struct ast_state *state, void* _o)
goto failed;
Py_DECREF(value);
break;
+ case TemplateStr_kind:
+ tp = (PyTypeObject *)state->TemplateStr_type;
+ result = PyType_GenericNew(tp, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_list(state, (asdl_seq*)o->v.TemplateStr.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);
@@ -14793,6 +14999,91 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena*
if (*out == NULL) goto failed;
return 0;
}
+ tp = state->Interpolation_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return -1;
+ }
+ if (isinstance) {
+ expr_ty value;
+ constant str;
+ int conversion;
+ expr_ty format_spec;
+
+ if (PyObject_GetOptionalAttr(obj, state->value, &tmp) < 0) {
+ return -1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Interpolation");
+ return -1;
+ }
+ else {
+ int res;
+ if (_Py_EnterRecursiveCall(" while traversing 'Interpolation' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &value, arena);
+ _Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (PyObject_GetOptionalAttr(obj, state->str, &tmp) < 0) {
+ return -1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"str\" missing from Interpolation");
+ return -1;
+ }
+ else {
+ int res;
+ if (_Py_EnterRecursiveCall(" while traversing 'Interpolation' node")) {
+ goto failed;
+ }
+ res = obj2ast_constant(state, tmp, &str, arena);
+ _Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (PyObject_GetOptionalAttr(obj, state->conversion, &tmp) < 0) {
+ return -1;
+ }
+ if (tmp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "required field \"conversion\" missing from Interpolation");
+ return -1;
+ }
+ else {
+ int res;
+ if (_Py_EnterRecursiveCall(" while traversing 'Interpolation' node")) {
+ goto failed;
+ }
+ res = obj2ast_int(state, tmp, &conversion, arena);
+ _Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ if (PyObject_GetOptionalAttr(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 'Interpolation' node")) {
+ goto failed;
+ }
+ res = obj2ast_expr(state, tmp, &format_spec, arena);
+ _Py_LeaveRecursiveCall();
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = _PyAST_Interpolation(value, str, 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) {
@@ -14844,6 +15135,57 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena*
if (*out == NULL) goto failed;
return 0;
}
+ tp = state->TemplateStr_type;
+ isinstance = PyObject_IsInstance(obj, tp);
+ if (isinstance == -1) {
+ return -1;
+ }
+ if (isinstance) {
+ asdl_expr_seq* values;
+
+ if (PyObject_GetOptionalAttr(obj, state->values, &tmp) < 0) {
+ return -1;
+ }
+ if (tmp == NULL) {
+ tmp = PyList_New(0);
+ if (tmp == NULL) {
+ return -1;
+ }
+ }
+ {
+ int res;
+ Py_ssize_t len;
+ Py_ssize_t i;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "TemplateStr field \"values\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ values = _Py_asdl_expr_seq_new(len, arena);
+ if (values == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ expr_ty val;
+ PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
+ if (_Py_EnterRecursiveCall(" while traversing 'TemplateStr' 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, "TemplateStr field \"values\" changed size during iteration");
+ goto failed;
+ }
+ asdl_seq_SET(values, i, val);
+ }
+ Py_CLEAR(tmp);
+ }
+ *out = _PyAST_TemplateStr(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) {
@@ -17794,9 +18136,16 @@ astmodule_exec(PyObject *m)
< 0) {
return -1;
}
+ if (PyModule_AddObjectRef(m, "Interpolation", state->Interpolation_type) <
+ 0) {
+ return -1;
+ }
if (PyModule_AddObjectRef(m, "JoinedStr", state->JoinedStr_type) < 0) {
return -1;
}
+ if (PyModule_AddObjectRef(m, "TemplateStr", state->TemplateStr_type) < 0) {
+ return -1;
+ }
if (PyModule_AddObjectRef(m, "Constant", state->Constant_type) < 0) {
return -1;
}
diff --git a/Python/ast.c b/Python/ast.c
index 7ee884357b4..e01dd0de51e 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -345,6 +345,9 @@ validate_expr(expr_ty exp, expr_context_ty ctx)
case JoinedStr_kind:
ret = validate_exprs(exp->v.JoinedStr.values, Load, 0);
break;
+ case TemplateStr_kind:
+ ret = validate_exprs(exp->v.TemplateStr.values, Load, 0);
+ break;
case FormattedValue_kind:
if (validate_expr(exp->v.FormattedValue.value, Load) == 0)
return 0;
@@ -354,6 +357,15 @@ validate_expr(expr_ty exp, expr_context_ty ctx)
}
ret = 1;
break;
+ case Interpolation_kind:
+ if (validate_expr(exp->v.Interpolation.value, Load) == 0)
+ return 0;
+ if (exp->v.Interpolation.format_spec) {
+ ret = validate_expr(exp->v.Interpolation.format_spec, Load);
+ break;
+ }
+ ret = 1;
+ break;
case Attribute_kind:
ret = validate_expr(exp->v.Attribute.value, Load);
break;
@@ -512,6 +524,7 @@ validate_pattern_match_value(expr_ty exp)
}
break;
case JoinedStr_kind:
+ case TemplateStr_kind:
// Handled in the later stages
return 1;
default:
diff --git a/Python/ast_opt.c b/Python/ast_opt.c
index 807de98ab5e..4d5e5589ac0 100644
--- a/Python/ast_opt.c
+++ b/Python/ast_opt.c
@@ -558,9 +558,16 @@ astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
CALL(astfold_expr, expr_ty, node_->v.FormattedValue.value);
CALL_OPT(astfold_expr, expr_ty, node_->v.FormattedValue.format_spec);
break;
+ case Interpolation_kind:
+ CALL(astfold_expr, expr_ty, node_->v.Interpolation.value);
+ CALL_OPT(astfold_expr, expr_ty, node_->v.Interpolation.format_spec);
+ break;
case JoinedStr_kind:
CALL_SEQ(astfold_expr, expr, node_->v.JoinedStr.values);
break;
+ case TemplateStr_kind:
+ CALL_SEQ(astfold_expr, expr, node_->v.TemplateStr.values);
+ break;
case Attribute_kind:
CALL(astfold_expr, expr_ty, node_->v.Attribute.value);
break;
diff --git a/Python/ast_unparse.c b/Python/ast_unparse.c
index f3c669c33eb..c121ec096ae 100644
--- a/Python/ast_unparse.c
+++ b/Python/ast_unparse.c
@@ -18,8 +18,12 @@ expr_as_unicode(expr_ty e, int level);
static int
append_ast_expr(PyUnicodeWriter *writer, expr_ty e, int level);
static int
+append_templatestr(PyUnicodeWriter *writer, expr_ty e);
+static int
append_joinedstr(PyUnicodeWriter *writer, expr_ty e, bool is_format_spec);
static int
+append_interpolation(PyUnicodeWriter *writer, expr_ty e);
+static int
append_formattedvalue(PyUnicodeWriter *writer, expr_ty e);
static int
append_ast_slice(PyUnicodeWriter *writer, expr_ty e);
@@ -621,11 +625,15 @@ append_fstring_element(PyUnicodeWriter *writer, expr_ty e, bool is_format_spec)
return append_fstring_unicode(writer, e->v.Constant.value);
case JoinedStr_kind:
return append_joinedstr(writer, e, is_format_spec);
+ case TemplateStr_kind:
+ return append_templatestr(writer, e);
case FormattedValue_kind:
return append_formattedvalue(writer, e);
+ case Interpolation_kind:
+ return append_interpolation(writer, e);
default:
PyErr_SetString(PyExc_SystemError,
- "unknown expression kind inside f-string");
+ "unknown expression kind inside f-string or t-string");
return -1;
}
}
@@ -633,7 +641,7 @@ append_fstring_element(PyUnicodeWriter *writer, expr_ty e, bool is_format_spec)
/* 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_expr_seq *values, bool is_format_spec)
+build_ftstring_body(asdl_expr_seq *values, bool is_format_spec)
{
PyUnicodeWriter *body_writer = PyUnicodeWriter_Create(256);
if (body_writer == NULL) {
@@ -655,10 +663,98 @@ build_fstring_body(asdl_expr_seq *values, bool is_format_spec)
}
static int
+_write_values_subarray(PyUnicodeWriter *writer, asdl_expr_seq *values, Py_ssize_t first_idx,
+ Py_ssize_t last_idx, char prefix, PyArena *arena)
+{
+ int result = -1;
+
+ asdl_expr_seq *new_values = _Py_asdl_expr_seq_new(last_idx - first_idx + 1, arena);
+ if (!new_values) {
+ return result;
+ }
+
+ Py_ssize_t j = 0;
+ for (Py_ssize_t i = first_idx; i <= last_idx; ++i) {
+ asdl_seq_SET(new_values, j++, asdl_seq_GET(values, i));
+ }
+
+ PyObject *body = build_ftstring_body(new_values, false);
+ if (!body) {
+ return result;
+ }
+
+ if (-1 != append_char(writer, prefix) &&
+ -1 != append_repr(writer, body))
+ {
+ result = 0;
+ }
+ Py_DECREF(body);
+ return result;
+}
+
+static int
+append_templatestr(PyUnicodeWriter *writer, expr_ty e)
+{
+ PyArena *arena = _PyArena_New();
+ if (!arena) {
+ return -1;
+ }
+
+ Py_ssize_t last_idx = 0;
+ Py_ssize_t len = asdl_seq_LEN(e->v.TemplateStr.values);
+ for (Py_ssize_t i = 0; i < len; i++) {
+ expr_ty value = asdl_seq_GET(e->v.TemplateStr.values, i);
+
+ // Handle implicit concat of t-strings with f-strings
+ if (value->kind == FormattedValue_kind) {
+ if (i > last_idx) {
+ // Create a new TemplateStr with the values between last_idx and i
+ // and append it to the writer.
+ if (_write_values_subarray(writer, e->v.TemplateStr.values,
+ last_idx, i - 1, 't', arena) == -1) {
+ goto error;
+ }
+
+ if (append_charp(writer, " ") == -1) {
+ goto error;
+ }
+ }
+
+ // Append the FormattedValue to the writer.
+ if (_write_values_subarray(writer, e->v.TemplateStr.values,
+ i, i, 'f', arena) == -1) {
+ goto error;
+ }
+
+ if (i + 1 < len) {
+ if (append_charp(writer, " ") == -1) {
+ goto error;
+ }
+ }
+
+ last_idx = i + 1;
+ }
+ }
+
+ if (last_idx < len) {
+ if (_write_values_subarray(writer, e->v.TemplateStr.values,
+ last_idx, len - 1, 't', arena) == -1) {
+ goto error;
+ }
+ }
+
+ return 0;
+
+error:
+ _PyArena_Free(arena);
+ return -1;
+}
+
+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);
+ PyObject *body = build_ftstring_body(e->v.JoinedStr.values, is_format_spec);
if (!body) {
return -1;
}
@@ -678,13 +774,12 @@ append_joinedstr(PyUnicodeWriter *writer, expr_ty e, bool is_format_spec)
}
static int
-append_formattedvalue(PyUnicodeWriter *writer, expr_ty e)
+append_interpolation_value(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);
+ PyObject *temp_fv_str = expr_as_unicode(e, PR_TEST + 1);
if (!temp_fv_str) {
return -1;
}
@@ -702,35 +797,81 @@ append_formattedvalue(PyUnicodeWriter *writer, expr_ty e)
return -1;
}
Py_DECREF(temp_fv_str);
+ return 0;
+}
- 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);
+static int
+append_interpolation_conversion(PyUnicodeWriter *writer, int conversion)
+{
+ if (conversion < 0) {
+ return 0;
}
- if (e->v.FormattedValue.format_spec) {
+
+ const char *conversion_str;
+ switch (conversion) {
+ case 'a':
+ conversion_str = "!a";
+ break;
+ case 'r':
+ conversion_str = "!r";
+ break;
+ case 's':
+ conversion_str = "!s";
+ break;
+ default:
+ PyErr_SetString(PyExc_SystemError,
+ "unknown f-value conversion kind");
+ return -1;
+ }
+ APPEND_STR(conversion_str);
+ return 0;
+}
+
+static int
+append_interpolation_format_spec(PyUnicodeWriter *writer, expr_ty e)
+{
+ if (e) {
if (-1 == PyUnicodeWriter_WriteChar(writer, ':') ||
- -1 == append_fstring_element(writer,
- e->v.FormattedValue.format_spec,
- true
- ))
+ -1 == append_fstring_element(writer, e, true))
{
return -1;
}
}
+ return 0;
+}
+
+static int
+append_interpolation(PyUnicodeWriter *writer, expr_ty e)
+{
+ if (-1 == append_interpolation_value(writer, e->v.Interpolation.value)) {
+ return -1;
+ }
+
+ if (-1 == append_interpolation_conversion(writer, e->v.Interpolation.conversion)) {
+ return -1;
+ }
+
+ if (-1 == append_interpolation_format_spec(writer, e->v.Interpolation.format_spec)) {
+ return -1;
+ }
+
+ APPEND_STR_FINISH("}");
+}
+
+static int
+append_formattedvalue(PyUnicodeWriter *writer, expr_ty e)
+{
+ if (-1 == append_interpolation_value(writer, e->v.FormattedValue.value)) {
+ return -1;
+ }
+
+ if (-1 == append_interpolation_conversion(writer, e->v.FormattedValue.conversion)) {
+ return -1;
+ }
+
+ if (-1 == append_interpolation_format_spec(writer, e->v.FormattedValue.format_spec)) {
+ return -1;
+ }
APPEND_CHAR_FINISH('}');
}
@@ -901,8 +1042,12 @@ append_ast_expr(PyUnicodeWriter *writer, expr_ty e, int level)
return append_ast_constant(writer, e->v.Constant.value);
case JoinedStr_kind:
return append_joinedstr(writer, e, false);
+ case TemplateStr_kind:
+ return append_templatestr(writer, e);
case FormattedValue_kind:
return append_formattedvalue(writer, e);
+ case Interpolation_kind:
+ return append_interpolation(writer, e);
/* The following exprs can be assignment targets. */
case Attribute_kind:
return append_ast_attribute(writer, e);
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 8ed0a96270b..3221d5acf96 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -566,11 +566,9 @@ filter_dealloc(PyObject *self)
{
filterobject *lz = _filterobject_CAST(self);
PyObject_GC_UnTrack(lz);
- Py_TRASHCAN_BEGIN(lz, filter_dealloc)
Py_XDECREF(lz->func);
Py_XDECREF(lz->it);
Py_TYPE(lz)->tp_free(lz);
- Py_TRASHCAN_END
}
static int
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 6592bc57ed2..496a53dbabe 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -16,6 +16,7 @@
#include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS
#include "pycore_function.h"
#include "pycore_instruments.h"
+#include "pycore_interpolation.h" // _PyInterpolation_Build()
#include "pycore_intrinsics.h"
#include "pycore_long.h" // _PyLong_GetZero()
#include "pycore_moduleobject.h" // PyModuleObject
@@ -30,6 +31,7 @@
#include "pycore_setobject.h" // _PySet_NextEntry()
#include "pycore_sliceobject.h" // _PyBuildSlice_ConsumeRefs
#include "pycore_stackref.h"
+#include "pycore_template.h" // _PyTemplate_Build()
#include "pycore_tuple.h" // _PyTuple_ITEMS()
#include "pycore_typeobject.h" // _PySuper_Lookup()
@@ -156,7 +158,7 @@ dummy_func(
QSBR_QUIESCENT_STATE(tstate);
if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) {
int err = _Py_HandlePending(tstate);
- ERROR_IF(err != 0, error);
+ ERROR_IF(err != 0);
}
}
@@ -166,7 +168,7 @@ dummy_func(
QSBR_QUIESCENT_STATE(tstate);
if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) {
int err = _Py_HandlePending(tstate);
- ERROR_IF(err != 0, error);
+ ERROR_IF(err != 0);
}
}
}
@@ -200,7 +202,7 @@ dummy_func(
((_PyThreadStateImpl *)tstate)->tlbc_index) {
_Py_CODEUNIT *bytecode =
_PyEval_GetExecutableCode(tstate, _PyFrame_GetCode(frame));
- ERROR_IF(bytecode == NULL, error);
+ ERROR_IF(bytecode == NULL);
ptrdiff_t off = this_instr - _PyFrame_GetBytecode(frame);
frame->tlbc_index = ((_PyThreadStateImpl *)tstate)->tlbc_index;
frame->instr_ptr = bytecode + off;
@@ -236,7 +238,7 @@ dummy_func(
op(_MONITOR_RESUME, (--)) {
int err = _Py_call_instrumentation(
tstate, oparg > 0, frame, this_instr);
- ERROR_IF(err, error);
+ ERROR_IF(err);
if (frame->instr_ptr != this_instr) {
/* Instrumentation has jumped */
next_instr = frame->instr_ptr;
@@ -260,7 +262,7 @@ dummy_func(
UNBOUNDLOCAL_ERROR_MSG,
PyTuple_GetItem(_PyFrame_GetCode(frame)->co_localsplusnames, oparg)
);
- ERROR_IF(1, error);
+ ERROR_IF(true);
}
value = PyStackRef_DUP(value_s);
}
@@ -446,7 +448,7 @@ dummy_func(
inst(UNARY_NEGATIVE, (value -- res)) {
PyObject *res_o = PyNumber_Negative(PyStackRef_AsPyObjectBorrow(value));
PyStackRef_CLOSE(value);
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -481,7 +483,7 @@ dummy_func(
op(_TO_BOOL, (value -- res)) {
int err = PyObject_IsTrue(PyStackRef_AsPyObjectBorrow(value));
PyStackRef_CLOSE(value);
- ERROR_IF(err < 0, error);
+ ERROR_IF(err < 0);
res = err ? PyStackRef_True : PyStackRef_False;
}
@@ -576,7 +578,7 @@ dummy_func(
inst(UNARY_INVERT, (value -- res)) {
PyObject *res_o = PyNumber_Invert(PyStackRef_AsPyObjectBorrow(value));
PyStackRef_CLOSE(value);
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -618,7 +620,7 @@ dummy_func(
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
INPUTS_DEAD();
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -633,7 +635,7 @@ dummy_func(
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
INPUTS_DEAD();
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -648,7 +650,7 @@ dummy_func(
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
INPUTS_DEAD();
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -681,7 +683,7 @@ dummy_func(
((PyFloatObject *)right_o)->ob_fval;
res = _PyFloat_FromDouble_ConsumeInputs(left, right, dres);
INPUTS_DEAD();
- ERROR_IF(PyStackRef_IsNull(res), error);
+ ERROR_IF(PyStackRef_IsNull(res));
}
pure op(_BINARY_OP_ADD_FLOAT, (left, right -- res)) {
@@ -696,7 +698,7 @@ dummy_func(
((PyFloatObject *)right_o)->ob_fval;
res = _PyFloat_FromDouble_ConsumeInputs(left, right, dres);
INPUTS_DEAD();
- ERROR_IF(PyStackRef_IsNull(res), error);
+ ERROR_IF(PyStackRef_IsNull(res));
}
pure op(_BINARY_OP_SUBTRACT_FLOAT, (left, right -- res)) {
@@ -711,7 +713,7 @@ dummy_func(
((PyFloatObject *)right_o)->ob_fval;
res = _PyFloat_FromDouble_ConsumeInputs(left, right, dres);
INPUTS_DEAD();
- ERROR_IF(PyStackRef_IsNull(res), error);
+ ERROR_IF(PyStackRef_IsNull(res));
}
macro(BINARY_OP_MULTIPLY_FLOAT) =
@@ -732,7 +734,7 @@ dummy_func(
PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc);
INPUTS_DEAD();
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -780,7 +782,7 @@ dummy_func(
PyUnicode_Append(&temp, right_o);
*target_local = PyStackRef_FromPyObjectSteal(temp);
Py_DECREF(right_o);
- ERROR_IF(PyStackRef_IsNull(*target_local), error);
+ ERROR_IF(PyStackRef_IsNull(*target_local));
#if TIER_ONE
// The STORE_FAST is already done. This is done here in tier one,
// and during trace projection in tier two:
@@ -839,7 +841,7 @@ dummy_func(
Py_DECREF(slice);
}
PyStackRef_CLOSE(container);
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -864,7 +866,7 @@ dummy_func(
Py_DECREF(slice);
}
DECREF_INPUTS();
- ERROR_IF(err, error);
+ ERROR_IF(err);
}
macro(STORE_SLICE) = _SPECIALIZE_STORE_SLICE + _STORE_SLICE;
@@ -978,7 +980,7 @@ dummy_func(
_PyErr_SetKeyError(sub);
}
DECREF_INPUTS();
- ERROR_IF(rc <= 0, error); // not found or error
+ ERROR_IF(rc <= 0); // not found or error
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -1016,13 +1018,13 @@ dummy_func(
inst(LIST_APPEND, (list, unused[oparg-1], v -- list, unused[oparg-1])) {
int err = _PyList_AppendTakeRef((PyListObject *)PyStackRef_AsPyObjectBorrow(list),
PyStackRef_AsPyObjectSteal(v));
- ERROR_IF(err < 0, error);
+ ERROR_IF(err < 0);
}
inst(SET_ADD, (set, unused[oparg-1], v -- set, unused[oparg-1])) {
int err = _PySet_AddTakeRef((PySetObject *)PyStackRef_AsPyObjectBorrow(set),
PyStackRef_AsPyObjectSteal(v));
- ERROR_IF(err, error);
+ ERROR_IF(err);
}
family(STORE_SUBSCR, INLINE_CACHE_ENTRIES_STORE_SUBSCR) = {
@@ -1046,7 +1048,7 @@ dummy_func(
/* container[sub] = v */
int err = PyObject_SetItem(PyStackRef_AsPyObjectBorrow(container), PyStackRef_AsPyObjectBorrow(sub), PyStackRef_AsPyObjectBorrow(v));
DECREF_INPUTS();
- ERROR_IF(err, error);
+ ERROR_IF(err);
}
macro(STORE_SUBSCR) = _SPECIALIZE_STORE_SUBSCR + _STORE_SUBSCR;
@@ -1095,7 +1097,7 @@ dummy_func(
PyStackRef_AsPyObjectSteal(sub),
PyStackRef_AsPyObjectSteal(value));
PyStackRef_CLOSE(dict_st);
- ERROR_IF(err, error);
+ ERROR_IF(err);
}
inst(DELETE_SUBSCR, (container, sub --)) {
@@ -1103,14 +1105,14 @@ dummy_func(
int err = PyObject_DelItem(PyStackRef_AsPyObjectBorrow(container),
PyStackRef_AsPyObjectBorrow(sub));
DECREF_INPUTS();
- ERROR_IF(err, error);
+ ERROR_IF(err);
}
inst(CALL_INTRINSIC_1, (value -- res)) {
assert(oparg <= MAX_INTRINSIC_1);
PyObject *res_o = _PyIntrinsics_UnaryFunctions[oparg].func(tstate, PyStackRef_AsPyObjectBorrow(value));
PyStackRef_CLOSE(value);
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -1121,7 +1123,7 @@ dummy_func(
PyObject *res_o = _PyIntrinsics_BinaryFunctions[oparg].func(tstate, value2, value1);
DECREF_INPUTS();
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -1135,7 +1137,7 @@ dummy_func(
monitor_reraise(tstate, frame, this_instr);
goto exception_unwind;
}
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
tier1 inst(INTERPRETER_EXIT, (retval --)) {
@@ -1173,7 +1175,7 @@ dummy_func(
int err = _Py_call_instrumentation_arg(
tstate, PY_MONITORING_EVENT_PY_RETURN,
frame, this_instr, PyStackRef_AsPyObjectBorrow(val));
- ERROR_IF(err, error);
+ ERROR_IF(err);
}
macro(INSTRUMENTED_RETURN_VALUE) =
@@ -1196,12 +1198,12 @@ dummy_func(
"__aiter__ method, got %.100s",
type->tp_name);
PyStackRef_CLOSE(obj);
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
iter_o = (*getter)(obj_o);
PyStackRef_CLOSE(obj);
- ERROR_IF(iter_o == NULL, error);
+ ERROR_IF(iter_o == NULL);
if (Py_TYPE(iter_o)->tp_as_async == NULL ||
Py_TYPE(iter_o)->tp_as_async->am_anext == NULL) {
@@ -1211,7 +1213,7 @@ dummy_func(
"that does not implement __anext__: %.100s",
Py_TYPE(iter_o)->tp_name);
Py_DECREF(iter_o);
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
iter = PyStackRef_FromPyObjectSteal(iter_o);
}
@@ -1227,7 +1229,7 @@ dummy_func(
inst(GET_AWAITABLE, (iterable -- iter)) {
PyObject *iter_o = _PyEval_GetAwaitable(PyStackRef_AsPyObjectBorrow(iterable), oparg);
PyStackRef_CLOSE(iterable);
- ERROR_IF(iter_o == NULL, error);
+ ERROR_IF(iter_o == NULL);
iter = PyStackRef_FromPyObjectSteal(iter_o);
}
@@ -1289,7 +1291,7 @@ dummy_func(
}
else {
PyStackRef_CLOSE(v);
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
}
PyStackRef_CLOSE(v);
@@ -1450,11 +1452,11 @@ dummy_func(
inst(LOAD_BUILD_CLASS, ( -- bc)) {
PyObject *bc_o;
int err = PyMapping_GetOptionalItem(BUILTINS(), &_Py_ID(__build_class__), &bc_o);
- ERROR_IF(err < 0, error);
+ ERROR_IF(err < 0);
if (bc_o == NULL) {
_PyErr_SetString(tstate, PyExc_NameError,
"__build_class__ not found");
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
bc = PyStackRef_FromPyObjectSteal(bc_o);
}
@@ -1467,7 +1469,7 @@ dummy_func(
_PyErr_Format(tstate, PyExc_SystemError,
"no locals found when storing %R", name);
PyStackRef_CLOSE(v);
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
if (PyDict_CheckExact(ns)) {
err = PyDict_SetItem(ns, name, PyStackRef_AsPyObjectBorrow(v));
@@ -1476,7 +1478,7 @@ dummy_func(
err = PyObject_SetItem(ns, name, PyStackRef_AsPyObjectBorrow(v));
}
PyStackRef_CLOSE(v);
- ERROR_IF(err, error);
+ ERROR_IF(err);
}
inst(DELETE_NAME, (--)) {
@@ -1522,7 +1524,7 @@ dummy_func(
PyObject *seq_o = PyStackRef_AsPyObjectSteal(seq);
int res = _PyEval_UnpackIterableStackRef(tstate, seq_o, oparg, -1, top);
Py_DECREF(seq_o);
- ERROR_IF(res == 0, error);
+ ERROR_IF(res == 0);
}
macro(UNPACK_SEQUENCE) = _SPECIALIZE_UNPACK_SEQUENCE + _UNPACK_SEQUENCE;
@@ -1580,7 +1582,7 @@ dummy_func(
PyObject *seq_o = PyStackRef_AsPyObjectSteal(seq);
int res = _PyEval_UnpackIterableStackRef(tstate, seq_o, oparg & 0xFF, oparg >> 8, top);
Py_DECREF(seq_o);
- ERROR_IF(res == 0, error);
+ ERROR_IF(res == 0);
}
family(STORE_ATTR, INLINE_CACHE_ENTRIES_STORE_ATTR) = {
@@ -1607,7 +1609,7 @@ dummy_func(
int err = PyObject_SetAttr(PyStackRef_AsPyObjectBorrow(owner),
name, PyStackRef_AsPyObjectBorrow(v));
DECREF_INPUTS();
- ERROR_IF(err, error);
+ ERROR_IF(err);
}
macro(STORE_ATTR) = _SPECIALIZE_STORE_ATTR + unused/3 + _STORE_ATTR;
@@ -1616,14 +1618,14 @@ dummy_func(
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
int err = PyObject_DelAttr(PyStackRef_AsPyObjectBorrow(owner), name);
PyStackRef_CLOSE(owner);
- ERROR_IF(err, error);
+ ERROR_IF(err);
}
inst(STORE_GLOBAL, (v --)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
int err = PyDict_SetItem(GLOBALS(), name, PyStackRef_AsPyObjectBorrow(v));
PyStackRef_CLOSE(v);
- ERROR_IF(err, error);
+ ERROR_IF(err);
}
inst(DELETE_GLOBAL, (--)) {
@@ -1645,7 +1647,7 @@ dummy_func(
if (l == NULL) {
_PyErr_SetString(tstate, PyExc_SystemError,
"no locals found");
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
locals = PyStackRef_FromPyObjectNew(l);
}
@@ -1655,7 +1657,7 @@ dummy_func(
PyObject *v_o;
int err = PyMapping_GetOptionalItem(PyStackRef_AsPyObjectBorrow(mod_or_class_dict), name, &v_o);
PyStackRef_CLOSE(mod_or_class_dict);
- ERROR_IF(err < 0, error);
+ ERROR_IF(err < 0);
if (v_o == NULL) {
if (PyDict_CheckExact(GLOBALS())
&& PyDict_CheckExact(BUILTINS()))
@@ -1677,16 +1679,16 @@ dummy_func(
/* Slow-path if globals or builtins is not a dict */
/* namespace 1: globals */
int err = PyMapping_GetOptionalItem(GLOBALS(), name, &v_o);
- ERROR_IF(err < 0, error);
+ ERROR_IF(err < 0);
if (v_o == NULL) {
/* namespace 2: builtins */
int err = PyMapping_GetOptionalItem(BUILTINS(), name, &v_o);
- ERROR_IF(err < 0, error);
+ ERROR_IF(err < 0);
if (v_o == NULL) {
_PyEval_FormatExcCheckArg(
tstate, PyExc_NameError,
NAME_ERROR_MSG, name);
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
}
}
@@ -1697,7 +1699,7 @@ dummy_func(
inst(LOAD_NAME, (-- v)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
PyObject *v_o = _PyEval_LoadName(tstate, frame, name);
- ERROR_IF(v_o == NULL, error);
+ ERROR_IF(v_o == NULL);
v = PyStackRef_FromPyObjectSteal(v_o);
}
@@ -1723,7 +1725,7 @@ dummy_func(
op(_LOAD_GLOBAL, ( -- res[1])) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
_PyEval_LoadGlobalStackRef(GLOBALS(), BUILTINS(), name, res);
- ERROR_IF(PyStackRef_IsNull(*res), error);
+ ERROR_IF(PyStackRef_IsNull(*res));
}
op(_PUSH_NULL_CONDITIONAL, ( -- null[oparg & 1])) {
@@ -1806,7 +1808,7 @@ dummy_func(
UNBOUNDLOCAL_ERROR_MSG,
PyTuple_GetItem(_PyFrame_GetCode(frame)->co_localsplusnames, oparg)
);
- ERROR_IF(1, error);
+ ERROR_IF(true);
}
_PyStackRef tmp = GETLOCAL(oparg);
GETLOCAL(oparg) = PyStackRef_NULL;
@@ -1867,7 +1869,7 @@ dummy_func(
value = _PyCell_GetStackRef(cell);
if (PyStackRef_IsNull(value)) {
_PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg);
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
}
@@ -1894,15 +1896,49 @@ dummy_func(
STACKREFS_TO_PYOBJECTS(pieces, oparg, pieces_o);
if (CONVERSION_FAILED(pieces_o)) {
DECREF_INPUTS();
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
PyObject *str_o = _PyUnicode_JoinArray(&_Py_STR(empty), pieces_o, oparg);
STACKREFS_TO_PYOBJECTS_CLEANUP(pieces_o);
DECREF_INPUTS();
- ERROR_IF(str_o == NULL, error);
+ ERROR_IF(str_o == NULL);
str = PyStackRef_FromPyObjectSteal(str_o);
}
+ inst(BUILD_INTERPOLATION, (value, str, format[oparg & 1] -- interpolation)) {
+ PyObject *value_o = PyStackRef_AsPyObjectBorrow(value);
+ PyObject *str_o = PyStackRef_AsPyObjectBorrow(str);
+ int conversion = oparg >> 2;
+ PyObject *format_o;
+ if (oparg & 1) {
+ format_o = PyStackRef_AsPyObjectBorrow(format[0]);
+ }
+ else {
+ format_o = &_Py_STR(empty);
+ }
+ PyObject *interpolation_o = _PyInterpolation_Build(value_o, str_o, conversion, format_o);
+ if (oparg & 1) {
+ PyStackRef_CLOSE(format[0]);
+ }
+ else {
+ DEAD(format);
+ }
+ PyStackRef_CLOSE(str);
+ PyStackRef_CLOSE(value);
+ ERROR_IF(interpolation_o == NULL);
+ interpolation = PyStackRef_FromPyObjectSteal(interpolation_o);
+ }
+
+ inst(BUILD_TEMPLATE, (strings, interpolations -- template)) {
+ PyObject *strings_o = PyStackRef_AsPyObjectBorrow(strings);
+ PyObject *interpolations_o = PyStackRef_AsPyObjectBorrow(interpolations);
+ PyObject *template_o = _PyTemplate_Build(strings_o, interpolations_o);
+ PyStackRef_CLOSE(interpolations);
+ PyStackRef_CLOSE(strings);
+ ERROR_IF(template_o == NULL);
+ template = PyStackRef_FromPyObjectSteal(template_o);
+ }
+
inst(BUILD_TUPLE, (values[oparg] -- tup)) {
PyObject *tup_o = _PyTuple_FromStackRefStealOnSuccess(values, oparg);
if (tup_o == NULL) {
@@ -1937,7 +1973,7 @@ dummy_func(
Py_TYPE(iterable)->tp_name);
}
PyStackRef_CLOSE(iterable_st);
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
assert(Py_IsNone(none_val));
PyStackRef_CLOSE(iterable_st);
@@ -1947,14 +1983,14 @@ dummy_func(
int err = _PySet_Update(PyStackRef_AsPyObjectBorrow(set),
PyStackRef_AsPyObjectBorrow(iterable));
PyStackRef_CLOSE(iterable);
- ERROR_IF(err < 0, error);
+ ERROR_IF(err < 0);
}
inst(BUILD_SET, (values[oparg] -- set)) {
PyObject *set_o = PySet_New(NULL);
if (set_o == NULL) {
DECREF_INPUTS();
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
int err = 0;
@@ -1971,7 +2007,7 @@ dummy_func(
DEAD(values);
if (err) {
Py_DECREF(set_o);
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
INPUTS_DEAD();
@@ -1982,7 +2018,7 @@ dummy_func(
STACKREFS_TO_PYOBJECTS(values, oparg*2, values_o);
if (CONVERSION_FAILED(values_o)) {
DECREF_INPUTS();
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
PyObject *map_o = _PyDict_FromItems(
values_o, 2,
@@ -1990,7 +2026,7 @@ dummy_func(
oparg);
STACKREFS_TO_PYOBJECTS_CLEANUP(values_o);
DECREF_INPUTS();
- ERROR_IF(map_o == NULL, error);
+ ERROR_IF(map_o == NULL);
map = PyStackRef_FromPyObjectStealMortal(map_o);
}
@@ -1999,18 +2035,18 @@ dummy_func(
if (LOCALS() == NULL) {
_PyErr_Format(tstate, PyExc_SystemError,
"no locals found when setting up annotations");
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
/* check if __annotations__ in locals()... */
int err = PyMapping_GetOptionalItem(LOCALS(), &_Py_ID(__annotations__), &ann_dict);
- ERROR_IF(err < 0, error);
+ ERROR_IF(err < 0);
if (ann_dict == NULL) {
ann_dict = PyDict_New();
- ERROR_IF(ann_dict == NULL, error);
+ ERROR_IF(ann_dict == NULL);
err = PyObject_SetItem(LOCALS(), &_Py_ID(__annotations__),
ann_dict);
Py_DECREF(ann_dict);
- ERROR_IF(err, error);
+ ERROR_IF(err);
}
else {
Py_DECREF(ann_dict);
@@ -2034,7 +2070,7 @@ dummy_func(
Py_TYPE(update_o)->tp_name);
}
PyStackRef_CLOSE(update);
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
PyStackRef_CLOSE(update);
}
@@ -2048,7 +2084,7 @@ dummy_func(
if (err < 0) {
_PyEval_FormatKwargsError(tstate, callable_o, update_o);
PyStackRef_CLOSE(update);
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
PyStackRef_CLOSE(update);
}
@@ -2063,7 +2099,7 @@ dummy_func(
PyStackRef_AsPyObjectSteal(key),
PyStackRef_AsPyObjectSteal(value)
);
- ERROR_IF(err != 0, error);
+ ERROR_IF(err != 0);
}
macro(INSTRUMENTED_LOAD_SUPER_ATTR) =
@@ -2101,7 +2137,7 @@ dummy_func(
frame, this_instr, global_super, arg);
if (err) {
DECREF_INPUTS();
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
}
// we make no attempt to optimize here; specializations should
@@ -2125,11 +2161,11 @@ dummy_func(
}
}
DECREF_INPUTS();
- ERROR_IF(super == NULL, error);
+ ERROR_IF(super == NULL);
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2);
PyObject *attr_o = PyObject_GetAttr(super, name);
Py_DECREF(super);
- ERROR_IF(attr_o == NULL, error);
+ ERROR_IF(attr_o == NULL);
attr = PyStackRef_FromPyObjectSteal(attr_o);
}
@@ -2150,7 +2186,7 @@ dummy_func(
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2);
PyObject *attr = _PySuper_Lookup((PyTypeObject *)class, self, name, NULL);
DECREF_INPUTS();
- ERROR_IF(attr == NULL, error);
+ ERROR_IF(attr == NULL);
attr_st = PyStackRef_FromPyObjectSteal(attr);
}
@@ -2236,7 +2272,7 @@ dummy_func(
meth | NULL | arg1 | ... | argN
*/
PyStackRef_CLOSE(owner);
- ERROR_IF(attr_o == NULL, error);
+ ERROR_IF(attr_o == NULL);
self_or_null[0] = PyStackRef_NULL;
}
}
@@ -2244,7 +2280,7 @@ dummy_func(
/* Classic, pushes one value. */
attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name);
PyStackRef_CLOSE(owner);
- ERROR_IF(attr_o == NULL, error);
+ ERROR_IF(attr_o == NULL);
}
attr = PyStackRef_FromPyObjectSteal(attr_o);
}
@@ -2608,11 +2644,11 @@ dummy_func(
assert((oparg >> 5) <= Py_GE);
PyObject *res_o = PyObject_RichCompare(left_o, right_o, oparg >> 5);
DECREF_INPUTS();
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
if (oparg & 16) {
int res_bool = PyObject_IsTrue(res_o);
Py_DECREF(res_o);
- ERROR_IF(res_bool < 0, error);
+ ERROR_IF(res_bool < 0);
res = res_bool ? PyStackRef_True : PyStackRef_False;
}
else {
@@ -2706,7 +2742,7 @@ dummy_func(
int res = PySequence_Contains(right_o, left_o);
DECREF_INPUTS();
- ERROR_IF(res < 0, error);
+ ERROR_IF(res < 0);
b = (res ^ oparg) ? PyStackRef_True : PyStackRef_False;
}
@@ -2740,7 +2776,7 @@ dummy_func(
// Note: both set and frozenset use the same seq_contains method!
int res = _PySet_Contains((PySetObject *)right_o, left_o);
DECREF_INPUTS();
- ERROR_IF(res < 0, error);
+ ERROR_IF(res < 0);
b = (res ^ oparg) ? PyStackRef_True : PyStackRef_False;
}
@@ -2754,7 +2790,7 @@ dummy_func(
STAT_INC(CONTAINS_OP, hit);
int res = PyDict_Contains(right_o, left_o);
DECREF_INPUTS();
- ERROR_IF(res < 0, error);
+ ERROR_IF(res < 0);
b = (res ^ oparg) ? PyStackRef_True : PyStackRef_False;
}
@@ -2764,7 +2800,7 @@ dummy_func(
int err = _PyEval_CheckExceptStarTypeValid(tstate, match_type);
if (err < 0) {
DECREF_INPUTS();
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
PyObject *match_o = NULL;
@@ -2772,10 +2808,10 @@ dummy_func(
int res = _PyEval_ExceptionGroupMatch(frame, exc_value, match_type,
&match_o, &rest_o);
DECREF_INPUTS();
- ERROR_IF(res < 0, error);
+ ERROR_IF(res < 0);
assert((match_o == NULL) == (rest_o == NULL));
- ERROR_IF(match_o == NULL, error);
+ ERROR_IF(match_o == NULL);
if (!Py_IsNone(match_o)) {
PyErr_SetHandledException(match_o);
@@ -2805,14 +2841,14 @@ dummy_func(
PyStackRef_AsPyObjectBorrow(fromlist),
PyStackRef_AsPyObjectBorrow(level));
DECREF_INPUTS();
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
inst(IMPORT_FROM, (from -- from, res)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
PyObject *res_o = _PyEval_ImportFrom(tstate, PyStackRef_AsPyObjectBorrow(from), name);
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -2850,7 +2886,7 @@ dummy_func(
int optimized = _PyOptimizer_Optimize(frame, start, &executor, 0);
if (optimized <= 0) {
this_instr[1].counter = restart_backoff_counter(counter);
- ERROR_IF(optimized < 0, error);
+ ERROR_IF(optimized < 0);
}
else {
this_instr[1].counter = initial_jump_backoff_counter();
@@ -2976,9 +3012,9 @@ dummy_func(
inst(GET_LEN, (obj -- obj, len)) {
// PUSH(len(TOS))
Py_ssize_t len_i = PyObject_Length(PyStackRef_AsPyObjectBorrow(obj));
- ERROR_IF(len_i < 0, error);
+ ERROR_IF(len_i < 0);
PyObject *len_o = PyLong_FromSsize_t(len_i);
- ERROR_IF(len_o == NULL, error);
+ ERROR_IF(len_o == NULL);
len = PyStackRef_FromPyObjectSteal(len_o);
}
@@ -2996,7 +3032,7 @@ dummy_func(
attrs = PyStackRef_FromPyObjectSteal(attrs_o);
}
else {
- ERROR_IF(_PyErr_Occurred(tstate), error); // Error!
+ ERROR_IF(_PyErr_Occurred(tstate)); // Error!
attrs = PyStackRef_None; // Failure!
}
}
@@ -3015,7 +3051,7 @@ dummy_func(
// On successful match, PUSH(values). Otherwise, PUSH(None).
PyObject *values_or_none_o = _PyEval_MatchKeys(tstate,
PyStackRef_AsPyObjectBorrow(subject), PyStackRef_AsPyObjectBorrow(keys));
- ERROR_IF(values_or_none_o == NULL, error);
+ ERROR_IF(values_or_none_o == NULL);
values_or_none = PyStackRef_FromPyObjectSteal(values_or_none_o);
}
@@ -3026,7 +3062,7 @@ dummy_func(
/* before: [obj]; after [getiter(obj)] */
PyObject *iter_o = PyObject_GetIter(PyStackRef_AsPyObjectBorrow(iterable));
PyStackRef_CLOSE(iterable);
- ERROR_IF(iter_o == NULL, error);
+ ERROR_IF(iter_o == NULL);
iter = PyStackRef_FromPyObjectSteal(iter_o);
}
@@ -3377,7 +3413,7 @@ dummy_func(
r->start = value + r->step;
r->len--;
PyObject *res = PyLong_FromLong(value);
- ERROR_IF(res == NULL, error);
+ ERROR_IF(res == NULL);
next = PyStackRef_FromPyObjectSteal(res);
}
@@ -3470,7 +3506,7 @@ dummy_func(
PyObject *res_o = PyObject_Vectorcall(exit_func_o, stack + 2 - has_self,
(3 + has_self) | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
Py_XDECREF(original_tb);
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -3704,7 +3740,7 @@ dummy_func(
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
if (CONVERSION_FAILED(args_o)) {
DECREF_INPUTS();
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
PyObject *res_o = PyObject_Vectorcall(
callable_o, args_o,
@@ -3730,7 +3766,7 @@ dummy_func(
}
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
DECREF_INPUTS();
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -3752,7 +3788,7 @@ dummy_func(
tstate, PY_MONITORING_EVENT_CALL,
frame, this_instr, function, arg0
);
- ERROR_IF(err, error);
+ ERROR_IF(err);
}
macro(CALL) = _SPECIALIZE_CALL + unused/2 + _MAYBE_EXPAND_METHOD + _DO_CALL + _CHECK_PERIODIC;
@@ -3857,7 +3893,7 @@ dummy_func(
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
if (CONVERSION_FAILED(args_o)) {
DECREF_INPUTS();
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
PyObject *res_o = PyObject_Vectorcall(
callable_o, args_o,
@@ -3866,7 +3902,7 @@ dummy_func(
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
DECREF_INPUTS();
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -4009,7 +4045,7 @@ dummy_func(
(void)callable; // Silence compiler warnings about unused variables
(void)null;
PyStackRef_CLOSE(arg);
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -4037,7 +4073,7 @@ dummy_func(
(void)callable; // Silence compiler warnings about unused variables
(void)null;
PyStackRef_CLOSE(arg);
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -4130,12 +4166,12 @@ dummy_func(
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
if (CONVERSION_FAILED(args_o)) {
DECREF_INPUTS();
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
PyObject *res_o = tp->tp_vectorcall((PyObject *)tp, args_o, total_args, NULL);
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
DECREF_INPUTS();
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -4170,7 +4206,7 @@ dummy_func(
DEAD(args);
DEAD(self_or_null);
PyStackRef_CLOSE(callable);
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -4198,7 +4234,7 @@ dummy_func(
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
if (CONVERSION_FAILED(args_o)) {
DECREF_INPUTS();
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
PyObject *res_o = _PyCFunctionFast_CAST(cfunc)(
PyCFunction_GET_SELF(callable_o),
@@ -4207,7 +4243,7 @@ dummy_func(
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
DECREF_INPUTS();
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -4237,13 +4273,13 @@ dummy_func(
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
if (CONVERSION_FAILED(args_o)) {
DECREF_INPUTS();
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
PyObject *res_o = cfunc(PyCFunction_GET_SELF(callable_o), args_o, total_args, NULL);
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
DECREF_INPUTS();
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -4325,7 +4361,7 @@ dummy_func(
UNLOCK_OBJECT(self_o);
PyStackRef_CLOSE(self);
PyStackRef_CLOSE(callable);
- ERROR_IF(err, error);
+ ERROR_IF(err);
#if TIER_ONE
// Skip the following POP_TOP. This is done here in tier one, and
// during trace projection in tier two:
@@ -4363,7 +4399,7 @@ dummy_func(
_Py_LeaveRecursiveCallTstate(tstate);
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
DECREF_INPUTS();
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -4397,7 +4433,7 @@ dummy_func(
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
if (CONVERSION_FAILED(args_o)) {
DECREF_INPUTS();
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
PyCFunctionFastWithKeywords cfunc =
_PyCFunctionFastWithKeywords_CAST(meth->ml_meth);
@@ -4405,7 +4441,7 @@ dummy_func(
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
DECREF_INPUTS();
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -4443,7 +4479,7 @@ dummy_func(
DEAD(args);
DEAD(self_or_null);
PyStackRef_CLOSE(callable);
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -4477,14 +4513,14 @@ dummy_func(
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
if (CONVERSION_FAILED(args_o)) {
DECREF_INPUTS();
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
PyCFunctionFast cfunc = _PyCFunctionFast_CAST(meth->ml_meth);
PyObject *res_o = cfunc(self, (args_o + 1), nargs);
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
DECREF_INPUTS();
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -4517,7 +4553,7 @@ dummy_func(
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_CALL,
frame, this_instr, function, arg);
- ERROR_IF(err, error);
+ ERROR_IF(err);
}
op(_MAYBE_EXPAND_METHOD_KW, (callable, self_or_null, unused[oparg], unused -- callable, self_or_null, unused[oparg], unused)) {
@@ -4574,7 +4610,7 @@ dummy_func(
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
if (CONVERSION_FAILED(args_o)) {
DECREF_INPUTS();
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
PyObject *res_o = PyObject_Vectorcall(
callable_o, args_o,
@@ -4599,7 +4635,7 @@ dummy_func(
}
}
DECREF_INPUTS();
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -4629,7 +4665,7 @@ dummy_func(
DEAD(self_or_null);
DEAD(callable);
SYNC_SP();
- ERROR_IF(temp == NULL, error);
+ ERROR_IF(temp == NULL);
new_frame = temp;
}
@@ -4727,7 +4763,7 @@ dummy_func(
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
if (CONVERSION_FAILED(args_o)) {
DECREF_INPUTS();
- ERROR_IF(true, error);
+ ERROR_IF(true);
}
PyObject *kwnames_o = PyStackRef_AsPyObjectBorrow(kwnames);
int positional_args = total_args - (int)PyTuple_GET_SIZE(kwnames_o);
@@ -4739,7 +4775,7 @@ dummy_func(
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
DECREF_INPUTS();
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -4842,7 +4878,7 @@ dummy_func(
PyStackRef_CLOSE(callargs_st);
DEAD(null);
PyStackRef_CLOSE(func_st);
- ERROR_IF(result_o == NULL, error);
+ ERROR_IF(result_o == NULL);
result = PyStackRef_FromPyObjectSteal(result_o);
}
@@ -4863,7 +4899,7 @@ dummy_func(
PyFunction_New(codeobj, GLOBALS());
PyStackRef_CLOSE(codeobj_st);
- ERROR_IF(func_obj == NULL, error);
+ ERROR_IF(func_obj == NULL);
_PyFunction_SetVersion(
func_obj, ((PyCodeObject *)codeobj)->co_version);
@@ -4887,7 +4923,7 @@ dummy_func(
assert(PyStackRef_FunctionCheck(frame->f_funcobj));
PyFunctionObject *func = (PyFunctionObject *)PyStackRef_AsPyObjectBorrow(frame->f_funcobj);
PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func);
- ERROR_IF(gen == NULL, error);
+ ERROR_IF(gen == NULL);
assert(STACK_LEVEL() == 0);
SAVE_STACK();
_PyInterpreterFrame *gen_frame = &gen->gi_iframe;
@@ -4912,7 +4948,7 @@ dummy_func(
PyObject *step_o = oparg == 3 ? PyStackRef_AsPyObjectBorrow(args[2]) : NULL;
PyObject *slice_o = PySlice_New(start_o, stop_o, step_o);
DECREF_INPUTS();
- ERROR_IF(slice_o == NULL, error);
+ ERROR_IF(slice_o == NULL);
slice = PyStackRef_FromPyObjectStealMortal(slice_o);
}
@@ -4922,7 +4958,7 @@ dummy_func(
conv_fn = _PyEval_ConversionFuncs[oparg];
PyObject *result_o = conv_fn(PyStackRef_AsPyObjectBorrow(value));
PyStackRef_CLOSE(value);
- ERROR_IF(result_o == NULL, error);
+ ERROR_IF(result_o == NULL);
result = PyStackRef_FromPyObjectSteal(result_o);
}
@@ -4933,7 +4969,7 @@ dummy_func(
if (!PyUnicode_CheckExact(value_o)) {
PyObject *res_o = PyObject_Format(value_o, NULL);
PyStackRef_CLOSE(value);
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
else {
@@ -4945,7 +4981,7 @@ dummy_func(
inst(FORMAT_WITH_SPEC, (value, fmt_spec -- res)) {
PyObject *res_o = PyObject_Format(PyStackRef_AsPyObjectBorrow(value), PyStackRef_AsPyObjectBorrow(fmt_spec));
DECREF_INPUTS();
- ERROR_IF(res_o == NULL, error);
+ ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -5024,7 +5060,7 @@ dummy_func(
inst(INSTRUMENTED_INSTRUCTION, ( -- )) {
int next_opcode = _Py_call_instrumentation_instruction(
tstate, frame, this_instr);
- ERROR_IF(next_opcode < 0, error);
+ ERROR_IF(next_opcode < 0);
next_instr = this_instr;
if (_PyOpcode_Caches[next_opcode]) {
PAUSE_ADAPTIVE_COUNTER(next_instr[1].counter);
@@ -5296,18 +5332,6 @@ dummy_func(
assert(tstate->tracing || eval_breaker == FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version));
}
- label(pop_4_error) {
- stack_pointer -= 4;
- assert(WITHIN_STACK_BOUNDS());
- goto error;
- }
-
- label(pop_3_error) {
- stack_pointer -= 3;
- assert(WITHIN_STACK_BOUNDS());
- goto error;
- }
-
label(pop_2_error) {
stack_pointer -= 2;
assert(WITHIN_STACK_BOUNDS());
diff --git a/Python/ceval.c b/Python/ceval.c
index 19a1c9529dd..4a75b60c9f0 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -19,6 +19,7 @@
#include "pycore_import.h" // _PyImport_IsDefaultImportFunc()
#include "pycore_instruments.h"
#include "pycore_interpframe.h" // _PyFrame_SetStackPointer()
+#include "pycore_interpolation.h" // _PyInterpolation_Build()
#include "pycore_intrinsics.h"
#include "pycore_jit.h"
#include "pycore_list.h" // _PyList_GetItemRef()
@@ -36,6 +37,7 @@
#include "pycore_setobject.h" // _PySet_Update()
#include "pycore_sliceobject.h" // _PyBuildSlice_ConsumeRefs
#include "pycore_sysmodule.h" // _PySys_GetOptionalAttrString()
+#include "pycore_template.h" // _PyTemplate_Build()
#include "pycore_traceback.h" // _PyTraceBack_FromFrame
#include "pycore_tuple.h" // _PyTuple_ITEMS()
#include "pycore_uop_ids.h" // Uops
@@ -480,12 +482,6 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where)
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
uintptr_t here_addr = _Py_get_machine_stack_pointer();
assert(_tstate->c_stack_soft_limit != 0);
- if (_tstate->c_stack_hard_limit == 0) {
- _Py_InitializeRecursionLimits(tstate);
- }
- if (here_addr >= _tstate->c_stack_soft_limit) {
- return 0;
- }
assert(_tstate->c_stack_hard_limit != 0);
if (here_addr < _tstate->c_stack_hard_limit) {
/* Overflowing while handling an overflow. Give up. */
diff --git a/Python/codecs.c b/Python/codecs.c
index 265f5214e5b..caf8d9d5f3c 100644
--- a/Python/codecs.c
+++ b/Python/codecs.c
@@ -540,11 +540,19 @@ PyObject * _PyCodec_LookupTextEncoding(const char *encoding,
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);
+ if (!is_text_codec) {
+ if (alternate_command != NULL) {
+ PyErr_Format(PyExc_LookupError,
+ "'%.400s' is not a text encoding; "
+ "use %s to handle arbitrary codecs",
+ encoding, alternate_command);
+ }
+ else {
+ PyErr_Format(PyExc_LookupError,
+ "'%.400s' is not a text encoding",
+ encoding);
+ }
+ }
return NULL;
}
}
diff --git a/Python/codegen.c b/Python/codegen.c
index a7e412f7032..c7662538408 100644
--- a/Python/codegen.c
+++ b/Python/codegen.c
@@ -3607,7 +3607,9 @@ infer_type(expr_ty e)
case Lambda_kind:
return &PyFunction_Type;
case JoinedStr_kind:
+ case TemplateStr_kind:
case FormattedValue_kind:
+ case Interpolation_kind:
return &PyUnicode_Type;
case Constant_kind:
return Py_TYPE(e->v.Constant.value);
@@ -3630,7 +3632,9 @@ check_caller(compiler *c, expr_ty e)
case SetComp_kind:
case GeneratorExp_kind:
case JoinedStr_kind:
- case FormattedValue_kind: {
+ case TemplateStr_kind:
+ case FormattedValue_kind:
+ case Interpolation_kind: {
location loc = LOC(e);
return _PyCompile_Warn(c, loc, "'%.200s' object is not callable; "
"perhaps you missed a comma?",
@@ -3693,7 +3697,9 @@ check_index(compiler *c, expr_ty e, expr_ty s)
case List_kind:
case ListComp_kind:
case JoinedStr_kind:
- case FormattedValue_kind: {
+ case TemplateStr_kind:
+ case FormattedValue_kind:
+ case Interpolation_kind: {
location loc = LOC(e);
return _PyCompile_Warn(c, loc, "%.200s indices must be integers "
"or slices, not %.200s; "
@@ -4044,6 +4050,59 @@ codegen_call(compiler *c, expr_ty e)
}
static int
+codegen_template_str(compiler *c, expr_ty e)
+{
+ location loc = LOC(e);
+ expr_ty value;
+
+ Py_ssize_t value_count = asdl_seq_LEN(e->v.TemplateStr.values);
+ int last_was_interpolation = 1;
+ Py_ssize_t stringslen = 0;
+ for (Py_ssize_t i = 0; i < value_count; i++) {
+ value = asdl_seq_GET(e->v.TemplateStr.values, i);
+ if (value->kind == Interpolation_kind) {
+ if (last_was_interpolation) {
+ ADDOP_LOAD_CONST(c, loc, Py_NewRef(&_Py_STR(empty)));
+ stringslen++;
+ }
+ last_was_interpolation = 1;
+ }
+ else {
+ VISIT(c, expr, value);
+ Py_ssize_t j;
+ for (j = i + 1; j < value_count; j++) {
+ value = asdl_seq_GET(e->v.TemplateStr.values, j);
+ if (value->kind == Interpolation_kind) {
+ break;
+ }
+ VISIT(c, expr, value);
+ ADDOP_INPLACE(c, loc, Add);
+ }
+ i = j - 1;
+ stringslen++;
+ last_was_interpolation = 0;
+ }
+ }
+ if (last_was_interpolation) {
+ ADDOP_LOAD_CONST(c, loc, Py_NewRef(&_Py_STR(empty)));
+ stringslen++;
+ }
+ ADDOP_I(c, loc, BUILD_TUPLE, stringslen);
+
+ Py_ssize_t interpolationslen = 0;
+ for (Py_ssize_t i = 0; i < value_count; i++) {
+ value = asdl_seq_GET(e->v.TemplateStr.values, i);
+ if (value->kind == Interpolation_kind) {
+ VISIT(c, expr, value);
+ interpolationslen++;
+ }
+ }
+ ADDOP_I(c, loc, BUILD_TUPLE, interpolationslen);
+ ADDOP(c, loc, BUILD_TEMPLATE);
+ return SUCCESS;
+}
+
+static int
codegen_joined_str(compiler *c, expr_ty e)
{
location loc = LOC(e);
@@ -4072,24 +4131,41 @@ codegen_joined_str(compiler *c, expr_ty e)
return SUCCESS;
}
-/* Used to implement f-strings. Format a single value. */
static int
-codegen_formatted_value(compiler *c, expr_ty e)
+codegen_interpolation(compiler *c, expr_ty e)
{
- /* Our oparg encodes 2 pieces of information: the conversion
- character, and whether or not a format_spec was provided.
+ location loc = LOC(e);
- 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
+ VISIT(c, expr, e->v.Interpolation.value);
+ ADDOP_LOAD_CONST(c, loc, e->v.Interpolation.str);
- next bit is whether or not we have a format spec:
- yes : 100 0x4
- no : 000 0x0
- */
+ int oparg = 2;
+ if (e->v.Interpolation.format_spec) {
+ oparg++;
+ VISIT(c, expr, e->v.Interpolation.format_spec);
+ }
+
+ int conversion = e->v.Interpolation.conversion;
+ if (conversion != -1) {
+ switch (conversion) {
+ case 's': oparg |= FVC_STR << 2; break;
+ case 'r': oparg |= FVC_REPR << 2; break;
+ case 'a': oparg |= FVC_ASCII << 2; break;
+ default:
+ PyErr_Format(PyExc_SystemError,
+ "Unrecognized conversion character %d", conversion);
+ return ERROR;
+ }
+ }
+
+ ADDOP_I(c, loc, BUILD_INTERPOLATION, oparg);
+ return SUCCESS;
+}
+/* Used to implement f-strings. Format a single value. */
+static int
+codegen_formatted_value(compiler *c, expr_ty e)
+{
int conversion = e->v.FormattedValue.conversion;
int oparg;
@@ -5182,8 +5258,12 @@ codegen_visit_expr(compiler *c, expr_ty e)
break;
case JoinedStr_kind:
return codegen_joined_str(c, e);
+ case TemplateStr_kind:
+ return codegen_template_str(c, e);
case FormattedValue_kind:
return codegen_formatted_value(c, e);
+ case Interpolation_kind:
+ return codegen_interpolation(c, e);
/* The following exprs can be assignment targets. */
case Attribute_kind:
if (e->v.Attribute.ctx == Load) {
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index 4e57906c84a..b37a87542fb 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -2604,6 +2604,89 @@
break;
}
+ case _BUILD_INTERPOLATION: {
+ _PyStackRef *format;
+ _PyStackRef str;
+ _PyStackRef value;
+ _PyStackRef interpolation;
+ oparg = CURRENT_OPARG();
+ format = &stack_pointer[-(oparg & 1)];
+ str = stack_pointer[-1 - (oparg & 1)];
+ value = stack_pointer[-2 - (oparg & 1)];
+ PyObject *value_o = PyStackRef_AsPyObjectBorrow(value);
+ PyObject *str_o = PyStackRef_AsPyObjectBorrow(str);
+ int conversion = oparg >> 2;
+ PyObject *format_o;
+ if (oparg & 1) {
+ format_o = PyStackRef_AsPyObjectBorrow(format[0]);
+ }
+ else {
+ format_o = &_Py_STR(empty);
+ }
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ PyObject *interpolation_o = _PyInterpolation_Build(value_o, str_o, conversion, format_o);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ if (oparg & 1) {
+ stack_pointer += -(oparg & 1);
+ assert(WITHIN_STACK_BOUNDS());
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ PyStackRef_CLOSE(format[0]);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ }
+ else {
+ stack_pointer += -(oparg & 1);
+ }
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ PyStackRef_CLOSE(str);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ PyStackRef_CLOSE(value);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ if (interpolation_o == NULL) {
+ JUMP_TO_ERROR();
+ }
+ interpolation = PyStackRef_FromPyObjectSteal(interpolation_o);
+ stack_pointer[0] = interpolation;
+ stack_pointer += 1;
+ assert(WITHIN_STACK_BOUNDS());
+ break;
+ }
+
+ case _BUILD_TEMPLATE: {
+ _PyStackRef interpolations;
+ _PyStackRef strings;
+ _PyStackRef template;
+ interpolations = stack_pointer[-1];
+ strings = stack_pointer[-2];
+ PyObject *strings_o = PyStackRef_AsPyObjectBorrow(strings);
+ PyObject *interpolations_o = PyStackRef_AsPyObjectBorrow(interpolations);
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ PyObject *template_o = _PyTemplate_Build(strings_o, interpolations_o);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ PyStackRef_CLOSE(interpolations);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ PyStackRef_CLOSE(strings);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ if (template_o == NULL) {
+ JUMP_TO_ERROR();
+ }
+ template = PyStackRef_FromPyObjectSteal(template_o);
+ stack_pointer[0] = template;
+ stack_pointer += 1;
+ assert(WITHIN_STACK_BOUNDS());
+ break;
+ }
+
case _BUILD_TUPLE: {
_PyStackRef *values;
_PyStackRef tup;
diff --git a/Python/gc.c b/Python/gc.c
index 58224acff2c..b7b48c8af39 100644
--- a/Python/gc.c
+++ b/Python/gc.c
@@ -2207,9 +2207,8 @@ void
PyObject_GC_UnTrack(void *op_raw)
{
PyObject *op = _PyObject_CAST(op_raw);
- /* Obscure: the Py_TRASHCAN mechanism requires that we be able to
- * call PyObject_GC_UnTrack twice on an object.
- */
+ /* The code for some objects, such as tuples, is a bit
+ * sloppy about when the object is tracked and untracked. */
if (_PyObject_GC_IS_TRACKED(op)) {
_PyObject_GC_UNTRACK(op);
}
diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c
index d22307ae4ff..2db75e0fd41 100644
--- a/Python/gc_free_threading.c
+++ b/Python/gc_free_threading.c
@@ -2511,9 +2511,8 @@ void
PyObject_GC_UnTrack(void *op_raw)
{
PyObject *op = _PyObject_CAST(op_raw);
- /* Obscure: the Py_TRASHCAN mechanism requires that we be able to
- * call PyObject_GC_UnTrack twice on an object.
- */
+ /* The code for some objects, such as tuples, is a bit
+ * sloppy about when the object is tracked and untracked. */
if (_PyObject_GC_IS_TRACKED(op)) {
_PyObject_GC_UNTRACK(op);
}
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 7d3e6c7cbc9..6841fbcc22e 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -1088,6 +1088,64 @@
DISPATCH();
}
+ TARGET(BUILD_INTERPOLATION) {
+ #if Py_TAIL_CALL_INTERP
+ int opcode = BUILD_INTERPOLATION;
+ (void)(opcode);
+ #endif
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(BUILD_INTERPOLATION);
+ _PyStackRef value;
+ _PyStackRef str;
+ _PyStackRef *format;
+ _PyStackRef interpolation;
+ format = &stack_pointer[-(oparg & 1)];
+ str = stack_pointer[-1 - (oparg & 1)];
+ value = stack_pointer[-2 - (oparg & 1)];
+ PyObject *value_o = PyStackRef_AsPyObjectBorrow(value);
+ PyObject *str_o = PyStackRef_AsPyObjectBorrow(str);
+ int conversion = oparg >> 2;
+ PyObject *format_o;
+ if (oparg & 1) {
+ format_o = PyStackRef_AsPyObjectBorrow(format[0]);
+ }
+ else {
+ format_o = &_Py_STR(empty);
+ }
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ PyObject *interpolation_o = _PyInterpolation_Build(value_o, str_o, conversion, format_o);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ if (oparg & 1) {
+ stack_pointer += -(oparg & 1);
+ assert(WITHIN_STACK_BOUNDS());
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ PyStackRef_CLOSE(format[0]);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ }
+ else {
+ stack_pointer += -(oparg & 1);
+ }
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ PyStackRef_CLOSE(str);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ PyStackRef_CLOSE(value);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ if (interpolation_o == NULL) {
+ JUMP_TO_LABEL(error);
+ }
+ interpolation = PyStackRef_FromPyObjectSteal(interpolation_o);
+ stack_pointer[0] = interpolation;
+ stack_pointer += 1;
+ assert(WITHIN_STACK_BOUNDS());
+ DISPATCH();
+ }
+
TARGET(BUILD_LIST) {
#if Py_TAIL_CALL_INTERP
int opcode = BUILD_LIST;
@@ -1303,6 +1361,44 @@
DISPATCH();
}
+ TARGET(BUILD_TEMPLATE) {
+ #if Py_TAIL_CALL_INTERP
+ int opcode = BUILD_TEMPLATE;
+ (void)(opcode);
+ #endif
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(BUILD_TEMPLATE);
+ _PyStackRef strings;
+ _PyStackRef interpolations;
+ _PyStackRef template;
+ interpolations = stack_pointer[-1];
+ strings = stack_pointer[-2];
+ PyObject *strings_o = PyStackRef_AsPyObjectBorrow(strings);
+ PyObject *interpolations_o = PyStackRef_AsPyObjectBorrow(interpolations);
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ PyObject *template_o = _PyTemplate_Build(strings_o, interpolations_o);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ PyStackRef_CLOSE(interpolations);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ PyStackRef_CLOSE(strings);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ if (template_o == NULL) {
+ JUMP_TO_LABEL(error);
+ }
+ template = PyStackRef_FromPyObjectSteal(template_o);
+ stack_pointer[0] = template;
+ stack_pointer += 1;
+ assert(WITHIN_STACK_BOUNDS());
+ DISPATCH();
+ }
+
TARGET(BUILD_TUPLE) {
#if Py_TAIL_CALL_INTERP
int opcode = BUILD_TUPLE;
@@ -7464,9 +7560,6 @@
PyObject *result = PyStackRef_AsPyObjectSteal(retval);
LLTRACE_RESUME_FRAME();
return result;
- stack_pointer += -1;
- assert(WITHIN_STACK_BOUNDS());
- DISPATCH();
}
TARGET(IS_OP) {
@@ -12137,20 +12230,6 @@ JUMP_TO_LABEL(error);
#endif /* Py_TAIL_CALL_INTERP */
/* BEGIN LABELS */
- LABEL(pop_4_error)
- {
- stack_pointer -= 4;
- assert(WITHIN_STACK_BOUNDS());
- JUMP_TO_LABEL(error);
- }
-
- LABEL(pop_3_error)
- {
- stack_pointer -= 3;
- assert(WITHIN_STACK_BOUNDS());
- JUMP_TO_LABEL(error);
- }
-
LABEL(pop_2_error)
{
stack_pointer -= 2;
diff --git a/Python/hamt.c b/Python/hamt.c
index e4d1e1663dd..f9bbf63961d 100644
--- a/Python/hamt.c
+++ b/Python/hamt.c
@@ -1118,7 +1118,6 @@ hamt_node_bitmap_dealloc(PyObject *self)
}
PyObject_GC_UnTrack(self);
- Py_TRASHCAN_BEGIN(self, hamt_node_bitmap_dealloc)
if (len > 0) {
i = len;
@@ -1128,7 +1127,6 @@ hamt_node_bitmap_dealloc(PyObject *self)
}
Py_TYPE(self)->tp_free(self);
- Py_TRASHCAN_END
}
#ifdef Py_DEBUG
@@ -1508,7 +1506,6 @@ hamt_node_collision_dealloc(PyObject *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) {
PyHamtNode_Collision *node = _PyHamtNode_Collision_CAST(self);
while (--len >= 0) {
@@ -1516,7 +1513,6 @@ hamt_node_collision_dealloc(PyObject *self)
}
}
Py_TYPE(self)->tp_free(self);
- Py_TRASHCAN_END
}
#ifdef Py_DEBUG
@@ -1878,13 +1874,11 @@ hamt_node_array_dealloc(PyObject *self)
{
/* Array's tp_dealloc */
PyObject_GC_UnTrack(self);
- Py_TRASHCAN_BEGIN(self, hamt_node_array_dealloc)
PyHamtNode_Array *obj = _PyHamtNode_Array_CAST(self);
for (Py_ssize_t i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) {
Py_XDECREF(obj->a_array[i]);
}
Py_TYPE(self)->tp_free(self);
- Py_TRASHCAN_END
}
#ifdef Py_DEBUG
diff --git a/Python/instruction_sequence.c b/Python/instruction_sequence.c
index b068e4fa3db..e2db46b4893 100644
--- a/Python/instruction_sequence.c
+++ b/Python/instruction_sequence.c
@@ -419,10 +419,8 @@ inst_seq_dealloc(PyObject *op)
{
_PyInstructionSequence *seq = (_PyInstructionSequence *)op;
PyObject_GC_UnTrack(seq);
- Py_TRASHCAN_BEGIN(seq, inst_seq_dealloc)
PyInstructionSequence_Fini(seq);
PyObject_GC_Del(seq);
- Py_TRASHCAN_END
}
static int
diff --git a/Python/intrinsics.c b/Python/intrinsics.c
index 1c7d7ee6c12..ff44ba0ee64 100644
--- a/Python/intrinsics.c
+++ b/Python/intrinsics.c
@@ -28,7 +28,6 @@ static PyObject *
print_expr(PyThreadState* Py_UNUSED(ignored), PyObject *value)
{
PyObject *hook = _PySys_GetRequiredAttr(&_Py_ID(displayhook));
- // Can't use ERROR_IF here.
if (hook == NULL) {
return NULL;
}
diff --git a/Python/jit.c b/Python/jit.c
index 8a91d2f62a4..e232cc1f7d9 100644
--- a/Python/jit.c
+++ b/Python/jit.c
@@ -12,6 +12,7 @@
#include "pycore_frame.h"
#include "pycore_function.h"
#include "pycore_interpframe.h"
+#include "pycore_interpolation.h"
#include "pycore_intrinsics.h"
#include "pycore_list.h"
#include "pycore_long.h"
@@ -21,6 +22,7 @@
#include "pycore_pyerrors.h"
#include "pycore_setobject.h"
#include "pycore_sliceobject.h"
+#include "pycore_template.h"
#include "pycore_tuple.h"
#include "pycore_unicodeobject.h"
diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h
index 5b9fb794c6b..8c2dfb46077 100644
--- a/Python/opcode_targets.h
+++ b/Python/opcode_targets.h
@@ -2,8 +2,9 @@
static void *opcode_targets[256] = {
&&TARGET_CACHE,
&&TARGET_BINARY_SLICE,
- &&TARGET_CALL_FUNCTION_EX,
+ &&TARGET_BUILD_TEMPLATE,
&&TARGET_BINARY_OP_INPLACE_ADD_UNICODE,
+ &&TARGET_CALL_FUNCTION_EX,
&&TARGET_CHECK_EG_MATCH,
&&TARGET_CHECK_EXC_MATCH,
&&TARGET_CLEANUP_THROW,
@@ -16,8 +17,8 @@ static void *opcode_targets[256] = {
&&TARGET_GET_AITER,
&&TARGET_GET_ANEXT,
&&TARGET_GET_ITER,
- &&TARGET_GET_LEN,
&&TARGET_RESERVED,
+ &&TARGET_GET_LEN,
&&TARGET_GET_YIELD_FROM_ITER,
&&TARGET_INTERPRETER_EXIT,
&&TARGET_LOAD_BUILD_CLASS,
@@ -44,6 +45,7 @@ static void *opcode_targets[256] = {
&&TARGET_UNARY_NOT,
&&TARGET_WITH_EXCEPT_START,
&&TARGET_BINARY_OP,
+ &&TARGET_BUILD_INTERPOLATION,
&&TARGET_BUILD_LIST,
&&TARGET_BUILD_MAP,
&&TARGET_BUILD_SET,
@@ -126,8 +128,6 @@ static void *opcode_targets[256] = {
&&_unknown_opcode,
&&_unknown_opcode,
&&_unknown_opcode,
- &&_unknown_opcode,
- &&_unknown_opcode,
&&TARGET_RESUME,
&&TARGET_BINARY_OP_ADD_FLOAT,
&&TARGET_BINARY_OP_ADD_INT,
@@ -260,8 +260,6 @@ static void *opcode_targets[256] = {
#else /* Py_TAIL_CALL_INTERP */
static py_tail_call_funcptr INSTRUCTION_TABLE[256];
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_pop_4_error(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_pop_3_error(TAIL_CALL_PARAMS);
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_pop_2_error(TAIL_CALL_PARAMS);
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_pop_1_error(TAIL_CALL_PARAMS);
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_error(TAIL_CALL_PARAMS);
@@ -285,11 +283,13 @@ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_SUBSCR_TUPLE_INT(TAIL_
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_SUBTRACT_FLOAT(TAIL_CALL_PARAMS);
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_SUBTRACT_INT(TAIL_CALL_PARAMS);
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_SLICE(TAIL_CALL_PARAMS);
+Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BUILD_INTERPOLATION(TAIL_CALL_PARAMS);
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BUILD_LIST(TAIL_CALL_PARAMS);
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BUILD_MAP(TAIL_CALL_PARAMS);
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BUILD_SET(TAIL_CALL_PARAMS);
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BUILD_SLICE(TAIL_CALL_PARAMS);
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BUILD_STRING(TAIL_CALL_PARAMS);
+Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BUILD_TEMPLATE(TAIL_CALL_PARAMS);
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BUILD_TUPLE(TAIL_CALL_PARAMS);
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CACHE(TAIL_CALL_PARAMS);
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL(TAIL_CALL_PARAMS);
@@ -521,11 +521,13 @@ static py_tail_call_funcptr INSTRUCTION_TABLE[256] = {
[BINARY_OP_SUBTRACT_FLOAT] = _TAIL_CALL_BINARY_OP_SUBTRACT_FLOAT,
[BINARY_OP_SUBTRACT_INT] = _TAIL_CALL_BINARY_OP_SUBTRACT_INT,
[BINARY_SLICE] = _TAIL_CALL_BINARY_SLICE,
+ [BUILD_INTERPOLATION] = _TAIL_CALL_BUILD_INTERPOLATION,
[BUILD_LIST] = _TAIL_CALL_BUILD_LIST,
[BUILD_MAP] = _TAIL_CALL_BUILD_MAP,
[BUILD_SET] = _TAIL_CALL_BUILD_SET,
[BUILD_SLICE] = _TAIL_CALL_BUILD_SLICE,
[BUILD_STRING] = _TAIL_CALL_BUILD_STRING,
+ [BUILD_TEMPLATE] = _TAIL_CALL_BUILD_TEMPLATE,
[BUILD_TUPLE] = _TAIL_CALL_BUILD_TUPLE,
[CACHE] = _TAIL_CALL_CACHE,
[CALL] = _TAIL_CALL_CALL,
@@ -729,8 +731,6 @@ static py_tail_call_funcptr INSTRUCTION_TABLE[256] = {
[UNPACK_SEQUENCE_TWO_TUPLE] = _TAIL_CALL_UNPACK_SEQUENCE_TWO_TUPLE,
[WITH_EXCEPT_START] = _TAIL_CALL_WITH_EXCEPT_START,
[YIELD_VALUE] = _TAIL_CALL_YIELD_VALUE,
- [119] = _TAIL_CALL_UNKNOWN_OPCODE,
- [120] = _TAIL_CALL_UNKNOWN_OPCODE,
[121] = _TAIL_CALL_UNKNOWN_OPCODE,
[122] = _TAIL_CALL_UNKNOWN_OPCODE,
[123] = _TAIL_CALL_UNKNOWN_OPCODE,
diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h
index 679240b6efa..b8391c59aaf 100644
--- a/Python/optimizer_cases.c.h
+++ b/Python/optimizer_cases.c.h
@@ -1039,6 +1039,24 @@
break;
}
+ case _BUILD_INTERPOLATION: {
+ JitOptSymbol *interpolation;
+ interpolation = sym_new_not_null(ctx);
+ stack_pointer[-2 - (oparg & 1)] = interpolation;
+ stack_pointer += -1 - (oparg & 1);
+ assert(WITHIN_STACK_BOUNDS());
+ break;
+ }
+
+ case _BUILD_TEMPLATE: {
+ JitOptSymbol *template;
+ template = sym_new_not_null(ctx);
+ stack_pointer[-2] = template;
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
+ break;
+ }
+
case _BUILD_TUPLE: {
JitOptSymbol **values;
JitOptSymbol *tup;
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 0871e147169..c4c1d9fd9e1 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -13,6 +13,7 @@
#include "pycore_freelist.h" // _PyObject_ClearFreeLists()
#include "pycore_global_objects_fini_generated.h" // _PyStaticObjects_CheckRefcnt()
#include "pycore_initconfig.h" // _PyStatus_OK()
+#include "pycore_interpolation.h" // _PyInterpolation_InitTypes()
#include "pycore_long.h" // _PyLong_InitTypes()
#include "pycore_object.h" // _PyDebug_PrintTotalRefs()
#include "pycore_obmalloc.h" // _PyMem_init_obmalloc()
@@ -754,6 +755,11 @@ pycore_init_types(PyInterpreterState *interp)
return status;
}
+ status = _PyInterpolation_InitTypes(interp);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
return _PyStatus_OK();
}
@@ -848,6 +854,10 @@ error:
static PyStatus
pycore_interp_init(PyThreadState *tstate)
{
+ _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
+ if (_tstate->c_stack_hard_limit == 0) {
+ _Py_InitializeRecursionLimits(tstate);
+ }
PyInterpreterState *interp = tstate->interp;
PyStatus status;
PyObject *sysmod = NULL;
diff --git a/Python/pystate.c b/Python/pystate.c
index b0c79ba9d3e..5685957b160 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -2168,7 +2168,10 @@ _PyThreadState_Attach(PyThreadState *tstate)
if (current_fast_get() != NULL) {
Py_FatalError("non-NULL old thread state");
}
-
+ _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
+ if (_tstate->c_stack_hard_limit == 0) {
+ _Py_InitializeRecursionLimits(tstate);
+ }
while (1) {
_PyEval_AcquireLock(tstate);
diff --git a/Python/symtable.c b/Python/symtable.c
index 2f13f35072a..f633e281019 100644
--- a/Python/symtable.c
+++ b/Python/symtable.c
@@ -2510,9 +2510,17 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
if (e->v.FormattedValue.format_spec)
VISIT(st, expr, e->v.FormattedValue.format_spec);
break;
+ case Interpolation_kind:
+ VISIT(st, expr, e->v.Interpolation.value);
+ if (e->v.Interpolation.format_spec)
+ VISIT(st, expr, e->v.Interpolation.format_spec);
+ break;
case JoinedStr_kind:
VISIT_SEQ(st, expr, e->v.JoinedStr.values);
break;
+ case TemplateStr_kind:
+ VISIT_SEQ(st, expr, e->v.TemplateStr.values);
+ break;
case Constant_kind:
/* Nothing to do here. */
break;
diff --git a/Python/traceback.c b/Python/traceback.c
index 0ac0b28201c..c06cb1a5908 100644
--- a/Python/traceback.c
+++ b/Python/traceback.c
@@ -236,11 +236,9 @@ tb_dealloc(PyObject *op)
{
PyTracebackObject *tb = _PyTracebackObject_CAST(op);
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