mirror of
https://github.com/python/cpython.git
synced 2025-08-23 18:24:46 +00:00
gh-132661: Implement PEP 750 (#132662)
Co-authored-by: Lysandros Nikolaou <lisandrosnik@gmail.com> Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Wingy <git@wingysam.xyz> Co-authored-by: Koudai Aono <koxudaxi@gmail.com> Co-authored-by: Dave Peck <davepeck@gmail.com> Co-authored-by: Terry Jan Reedy <tjreedy@udel.edu> Co-authored-by: Paul Everitt <pauleveritt@me.com> Co-authored-by: sobolevn <mail@sobolevn.me>
This commit is contained in:
parent
5ea9010e89
commit
60202609a2
81 changed files with 7716 additions and 3761 deletions
349
Python/Python-ast.c
generated
349
Python/Python-ast.c
generated
|
@ -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)");
|
||||
|
@ -8038,6 +8160,37 @@ _PyAST_FormattedValue(expr_ty value, int conversion, expr_ty format_spec, int
|
|||
return p;
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -8055,6 +8208,23 @@ _PyAST_JoinedStr(asdl_expr_seq * values, int lineno, int col_offset, int
|
|||
return p;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue