mirror of
https://github.com/python/cpython.git
synced 2025-08-27 12:16:04 +00:00
bpo-32892: Use ast.Constant instead of specific constant AST types. (GH-9445)
This commit is contained in:
parent
a94ee12c26
commit
3f22811fef
20 changed files with 337 additions and 678 deletions
312
Python/Python-ast.c
generated
312
Python/Python-ast.c
generated
|
@ -284,16 +284,6 @@ static char *Call_fields[]={
|
|||
"args",
|
||||
"keywords",
|
||||
};
|
||||
static PyTypeObject *Num_type;
|
||||
_Py_IDENTIFIER(n);
|
||||
static char *Num_fields[]={
|
||||
"n",
|
||||
};
|
||||
static PyTypeObject *Str_type;
|
||||
_Py_IDENTIFIER(s);
|
||||
static char *Str_fields[]={
|
||||
"s",
|
||||
};
|
||||
static PyTypeObject *FormattedValue_type;
|
||||
_Py_IDENTIFIER(conversion);
|
||||
_Py_IDENTIFIER(format_spec);
|
||||
|
@ -306,15 +296,6 @@ static PyTypeObject *JoinedStr_type;
|
|||
static char *JoinedStr_fields[]={
|
||||
"values",
|
||||
};
|
||||
static PyTypeObject *Bytes_type;
|
||||
static char *Bytes_fields[]={
|
||||
"s",
|
||||
};
|
||||
static PyTypeObject *NameConstant_type;
|
||||
static char *NameConstant_fields[]={
|
||||
"value",
|
||||
};
|
||||
static PyTypeObject *Ellipsis_type;
|
||||
static PyTypeObject *Constant_type;
|
||||
static char *Constant_fields[]={
|
||||
"value",
|
||||
|
@ -736,17 +717,6 @@ static PyObject* ast2obj_int(long b)
|
|||
|
||||
/* Conversion Python -> AST */
|
||||
|
||||
static int obj2ast_singleton(PyObject *obj, PyObject** out, PyArena* arena)
|
||||
{
|
||||
if (obj != Py_None && obj != Py_True && obj != Py_False) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"AST singleton must be True, False, or None");
|
||||
return 1;
|
||||
}
|
||||
*out = obj;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int obj2ast_object(PyObject* obj, PyObject** out, PyArena* arena)
|
||||
{
|
||||
if (obj == Py_None)
|
||||
|
@ -764,13 +734,11 @@ static int obj2ast_object(PyObject* obj, PyObject** out, PyArena* arena)
|
|||
|
||||
static int obj2ast_constant(PyObject* obj, PyObject** out, PyArena* arena)
|
||||
{
|
||||
if (obj) {
|
||||
if (PyArena_AddPyObject(arena, obj) < 0) {
|
||||
*out = NULL;
|
||||
return -1;
|
||||
}
|
||||
Py_INCREF(obj);
|
||||
if (PyArena_AddPyObject(arena, obj) < 0) {
|
||||
*out = NULL;
|
||||
return -1;
|
||||
}
|
||||
Py_INCREF(obj);
|
||||
*out = obj;
|
||||
return 0;
|
||||
}
|
||||
|
@ -784,24 +752,6 @@ static int obj2ast_identifier(PyObject* obj, PyObject** out, PyArena* arena)
|
|||
return obj2ast_object(obj, out, arena);
|
||||
}
|
||||
|
||||
static int obj2ast_string(PyObject* obj, PyObject** out, PyArena* arena)
|
||||
{
|
||||
if (!PyUnicode_CheckExact(obj) && !PyBytes_CheckExact(obj)) {
|
||||
PyErr_SetString(PyExc_TypeError, "AST string must be of type str");
|
||||
return 1;
|
||||
}
|
||||
return obj2ast_object(obj, out, arena);
|
||||
}
|
||||
|
||||
static int obj2ast_bytes(PyObject* obj, PyObject** out, PyArena* arena)
|
||||
{
|
||||
if (!PyBytes_CheckExact(obj)) {
|
||||
PyErr_SetString(PyExc_TypeError, "AST bytes must be of type bytes");
|
||||
return 1;
|
||||
}
|
||||
return obj2ast_object(obj, out, arena);
|
||||
}
|
||||
|
||||
static int obj2ast_int(PyObject* obj, int* out, PyArena* arena)
|
||||
{
|
||||
int i;
|
||||
|
@ -943,22 +893,11 @@ static int init_types(void)
|
|||
if (!Compare_type) return 0;
|
||||
Call_type = make_type("Call", expr_type, Call_fields, 3);
|
||||
if (!Call_type) return 0;
|
||||
Num_type = make_type("Num", expr_type, Num_fields, 1);
|
||||
if (!Num_type) return 0;
|
||||
Str_type = make_type("Str", expr_type, Str_fields, 1);
|
||||
if (!Str_type) return 0;
|
||||
FormattedValue_type = make_type("FormattedValue", expr_type,
|
||||
FormattedValue_fields, 3);
|
||||
if (!FormattedValue_type) return 0;
|
||||
JoinedStr_type = make_type("JoinedStr", expr_type, JoinedStr_fields, 1);
|
||||
if (!JoinedStr_type) return 0;
|
||||
Bytes_type = make_type("Bytes", expr_type, Bytes_fields, 1);
|
||||
if (!Bytes_type) return 0;
|
||||
NameConstant_type = make_type("NameConstant", expr_type,
|
||||
NameConstant_fields, 1);
|
||||
if (!NameConstant_type) return 0;
|
||||
Ellipsis_type = make_type("Ellipsis", expr_type, NULL, 0);
|
||||
if (!Ellipsis_type) return 0;
|
||||
Constant_type = make_type("Constant", expr_type, Constant_fields, 1);
|
||||
if (!Constant_type) return 0;
|
||||
Attribute_type = make_type("Attribute", expr_type, Attribute_fields, 3);
|
||||
|
@ -2089,44 +2028,6 @@ Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, int lineno, int
|
|||
return p;
|
||||
}
|
||||
|
||||
expr_ty
|
||||
Num(object n, int lineno, int col_offset, PyArena *arena)
|
||||
{
|
||||
expr_ty p;
|
||||
if (!n) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"field n is required for Num");
|
||||
return NULL;
|
||||
}
|
||||
p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
|
||||
if (!p)
|
||||
return NULL;
|
||||
p->kind = Num_kind;
|
||||
p->v.Num.n = n;
|
||||
p->lineno = lineno;
|
||||
p->col_offset = col_offset;
|
||||
return p;
|
||||
}
|
||||
|
||||
expr_ty
|
||||
Str(string s, int lineno, int col_offset, PyArena *arena)
|
||||
{
|
||||
expr_ty p;
|
||||
if (!s) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"field s is required for Str");
|
||||
return NULL;
|
||||
}
|
||||
p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
|
||||
if (!p)
|
||||
return NULL;
|
||||
p->kind = Str_kind;
|
||||
p->v.Str.s = s;
|
||||
p->lineno = lineno;
|
||||
p->col_offset = col_offset;
|
||||
return p;
|
||||
}
|
||||
|
||||
expr_ty
|
||||
FormattedValue(expr_ty value, int conversion, expr_ty format_spec, int lineno,
|
||||
int col_offset, PyArena *arena)
|
||||
|
@ -2163,57 +2064,6 @@ JoinedStr(asdl_seq * values, int lineno, int col_offset, PyArena *arena)
|
|||
return p;
|
||||
}
|
||||
|
||||
expr_ty
|
||||
Bytes(bytes s, int lineno, int col_offset, PyArena *arena)
|
||||
{
|
||||
expr_ty p;
|
||||
if (!s) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"field s is required for Bytes");
|
||||
return NULL;
|
||||
}
|
||||
p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
|
||||
if (!p)
|
||||
return NULL;
|
||||
p->kind = Bytes_kind;
|
||||
p->v.Bytes.s = s;
|
||||
p->lineno = lineno;
|
||||
p->col_offset = col_offset;
|
||||
return p;
|
||||
}
|
||||
|
||||
expr_ty
|
||||
NameConstant(singleton value, int lineno, int col_offset, PyArena *arena)
|
||||
{
|
||||
expr_ty p;
|
||||
if (!value) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"field value is required for NameConstant");
|
||||
return NULL;
|
||||
}
|
||||
p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
|
||||
if (!p)
|
||||
return NULL;
|
||||
p->kind = NameConstant_kind;
|
||||
p->v.NameConstant.value = value;
|
||||
p->lineno = lineno;
|
||||
p->col_offset = col_offset;
|
||||
return p;
|
||||
}
|
||||
|
||||
expr_ty
|
||||
Ellipsis(int lineno, int col_offset, PyArena *arena)
|
||||
{
|
||||
expr_ty p;
|
||||
p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
|
||||
if (!p)
|
||||
return NULL;
|
||||
p->kind = Ellipsis_kind;
|
||||
p->lineno = lineno;
|
||||
p->col_offset = col_offset;
|
||||
return p;
|
||||
}
|
||||
|
||||
expr_ty
|
||||
Constant(constant value, int lineno, int col_offset, PyArena *arena)
|
||||
{
|
||||
|
@ -3289,24 +3139,6 @@ ast2obj_expr(void* _o)
|
|||
goto failed;
|
||||
Py_DECREF(value);
|
||||
break;
|
||||
case Num_kind:
|
||||
result = PyType_GenericNew(Num_type, NULL, NULL);
|
||||
if (!result) goto failed;
|
||||
value = ast2obj_object(o->v.Num.n);
|
||||
if (!value) goto failed;
|
||||
if (_PyObject_SetAttrId(result, &PyId_n, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
break;
|
||||
case Str_kind:
|
||||
result = PyType_GenericNew(Str_type, NULL, NULL);
|
||||
if (!result) goto failed;
|
||||
value = ast2obj_string(o->v.Str.s);
|
||||
if (!value) goto failed;
|
||||
if (_PyObject_SetAttrId(result, &PyId_s, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
break;
|
||||
case FormattedValue_kind:
|
||||
result = PyType_GenericNew(FormattedValue_type, NULL, NULL);
|
||||
if (!result) goto failed;
|
||||
|
@ -3335,28 +3167,6 @@ ast2obj_expr(void* _o)
|
|||
goto failed;
|
||||
Py_DECREF(value);
|
||||
break;
|
||||
case Bytes_kind:
|
||||
result = PyType_GenericNew(Bytes_type, NULL, NULL);
|
||||
if (!result) goto failed;
|
||||
value = ast2obj_bytes(o->v.Bytes.s);
|
||||
if (!value) goto failed;
|
||||
if (_PyObject_SetAttrId(result, &PyId_s, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
break;
|
||||
case NameConstant_kind:
|
||||
result = PyType_GenericNew(NameConstant_type, NULL, NULL);
|
||||
if (!result) goto failed;
|
||||
value = ast2obj_singleton(o->v.NameConstant.value);
|
||||
if (!value) goto failed;
|
||||
if (_PyObject_SetAttrId(result, &PyId_value, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
break;
|
||||
case Ellipsis_kind:
|
||||
result = PyType_GenericNew(Ellipsis_type, NULL, NULL);
|
||||
if (!result) goto failed;
|
||||
break;
|
||||
case Constant_kind:
|
||||
result = PyType_GenericNew(Constant_type, NULL, NULL);
|
||||
if (!result) goto failed;
|
||||
|
@ -6606,54 +6416,6 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena)
|
|||
if (*out == NULL) goto failed;
|
||||
return 0;
|
||||
}
|
||||
isinstance = PyObject_IsInstance(obj, (PyObject*)Num_type);
|
||||
if (isinstance == -1) {
|
||||
return 1;
|
||||
}
|
||||
if (isinstance) {
|
||||
object n;
|
||||
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_n, &tmp) < 0) {
|
||||
return 1;
|
||||
}
|
||||
if (tmp == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "required field \"n\" missing from Num");
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
int res;
|
||||
res = obj2ast_object(tmp, &n, arena);
|
||||
if (res != 0) goto failed;
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = Num(n, lineno, col_offset, arena);
|
||||
if (*out == NULL) goto failed;
|
||||
return 0;
|
||||
}
|
||||
isinstance = PyObject_IsInstance(obj, (PyObject*)Str_type);
|
||||
if (isinstance == -1) {
|
||||
return 1;
|
||||
}
|
||||
if (isinstance) {
|
||||
string s;
|
||||
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_s, &tmp) < 0) {
|
||||
return 1;
|
||||
}
|
||||
if (tmp == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "required field \"s\" missing from Str");
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
int res;
|
||||
res = obj2ast_string(tmp, &s, arena);
|
||||
if (res != 0) goto failed;
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = Str(s, lineno, col_offset, arena);
|
||||
if (*out == NULL) goto failed;
|
||||
return 0;
|
||||
}
|
||||
isinstance = PyObject_IsInstance(obj, (PyObject*)FormattedValue_type);
|
||||
if (isinstance == -1) {
|
||||
return 1;
|
||||
|
@ -6748,64 +6510,6 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena)
|
|||
if (*out == NULL) goto failed;
|
||||
return 0;
|
||||
}
|
||||
isinstance = PyObject_IsInstance(obj, (PyObject*)Bytes_type);
|
||||
if (isinstance == -1) {
|
||||
return 1;
|
||||
}
|
||||
if (isinstance) {
|
||||
bytes s;
|
||||
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_s, &tmp) < 0) {
|
||||
return 1;
|
||||
}
|
||||
if (tmp == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "required field \"s\" missing from Bytes");
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
int res;
|
||||
res = obj2ast_bytes(tmp, &s, arena);
|
||||
if (res != 0) goto failed;
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = Bytes(s, lineno, col_offset, arena);
|
||||
if (*out == NULL) goto failed;
|
||||
return 0;
|
||||
}
|
||||
isinstance = PyObject_IsInstance(obj, (PyObject*)NameConstant_type);
|
||||
if (isinstance == -1) {
|
||||
return 1;
|
||||
}
|
||||
if (isinstance) {
|
||||
singleton value;
|
||||
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) {
|
||||
return 1;
|
||||
}
|
||||
if (tmp == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from NameConstant");
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
int res;
|
||||
res = obj2ast_singleton(tmp, &value, arena);
|
||||
if (res != 0) goto failed;
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = NameConstant(value, lineno, col_offset, arena);
|
||||
if (*out == NULL) goto failed;
|
||||
return 0;
|
||||
}
|
||||
isinstance = PyObject_IsInstance(obj, (PyObject*)Ellipsis_type);
|
||||
if (isinstance == -1) {
|
||||
return 1;
|
||||
}
|
||||
if (isinstance) {
|
||||
|
||||
*out = Ellipsis(lineno, col_offset, arena);
|
||||
if (*out == NULL) goto failed;
|
||||
return 0;
|
||||
}
|
||||
isinstance = PyObject_IsInstance(obj, (PyObject*)Constant_type);
|
||||
if (isinstance == -1) {
|
||||
return 1;
|
||||
|
@ -8244,18 +7948,10 @@ PyInit__ast(void)
|
|||
if (PyDict_SetItemString(d, "Compare", (PyObject*)Compare_type) < 0) return
|
||||
NULL;
|
||||
if (PyDict_SetItemString(d, "Call", (PyObject*)Call_type) < 0) return NULL;
|
||||
if (PyDict_SetItemString(d, "Num", (PyObject*)Num_type) < 0) return NULL;
|
||||
if (PyDict_SetItemString(d, "Str", (PyObject*)Str_type) < 0) return NULL;
|
||||
if (PyDict_SetItemString(d, "FormattedValue",
|
||||
(PyObject*)FormattedValue_type) < 0) return NULL;
|
||||
if (PyDict_SetItemString(d, "JoinedStr", (PyObject*)JoinedStr_type) < 0)
|
||||
return NULL;
|
||||
if (PyDict_SetItemString(d, "Bytes", (PyObject*)Bytes_type) < 0) return
|
||||
NULL;
|
||||
if (PyDict_SetItemString(d, "NameConstant", (PyObject*)NameConstant_type) <
|
||||
0) return NULL;
|
||||
if (PyDict_SetItemString(d, "Ellipsis", (PyObject*)Ellipsis_type) < 0)
|
||||
return NULL;
|
||||
if (PyDict_SetItemString(d, "Constant", (PyObject*)Constant_type) < 0)
|
||||
return NULL;
|
||||
if (PyDict_SetItemString(d, "Attribute", (PyObject*)Attribute_type) < 0)
|
||||
|
|
82
Python/ast.c
82
Python/ast.c
|
@ -295,23 +295,6 @@ validate_expr(expr_ty exp, expr_context_ty ctx)
|
|||
return 0;
|
||||
}
|
||||
return 1;
|
||||
case Num_kind: {
|
||||
PyObject *n = exp->v.Num.n;
|
||||
if (!PyLong_CheckExact(n) && !PyFloat_CheckExact(n) &&
|
||||
!PyComplex_CheckExact(n)) {
|
||||
PyErr_SetString(PyExc_TypeError, "non-numeric type in Num");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
case Str_kind: {
|
||||
PyObject *s = exp->v.Str.s;
|
||||
if (!PyUnicode_CheckExact(s)) {
|
||||
PyErr_SetString(PyExc_TypeError, "non-string type in Str");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
case JoinedStr_kind:
|
||||
return validate_exprs(exp->v.JoinedStr.values, Load, 0);
|
||||
case FormattedValue_kind:
|
||||
|
@ -320,14 +303,6 @@ validate_expr(expr_ty exp, expr_context_ty ctx)
|
|||
if (exp->v.FormattedValue.format_spec)
|
||||
return validate_expr(exp->v.FormattedValue.format_spec, Load);
|
||||
return 1;
|
||||
case Bytes_kind: {
|
||||
PyObject *b = exp->v.Bytes.s;
|
||||
if (!PyBytes_CheckExact(b)) {
|
||||
PyErr_SetString(PyExc_TypeError, "non-bytes type in Bytes");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
case Attribute_kind:
|
||||
return validate_expr(exp->v.Attribute.value, Load);
|
||||
case Subscript_kind:
|
||||
|
@ -339,10 +314,8 @@ validate_expr(expr_ty exp, expr_context_ty ctx)
|
|||
return validate_exprs(exp->v.List.elts, ctx, 0);
|
||||
case Tuple_kind:
|
||||
return validate_exprs(exp->v.Tuple.elts, ctx, 0);
|
||||
/* These last cases don't have any checking. */
|
||||
/* This last case doesn't have any checking. */
|
||||
case Name_kind:
|
||||
case NameConstant_kind:
|
||||
case Ellipsis_kind:
|
||||
return 1;
|
||||
default:
|
||||
PyErr_SetString(PyExc_SystemError, "unexpected expression");
|
||||
|
@ -1040,19 +1013,23 @@ set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n)
|
|||
break;
|
||||
case Dict_kind:
|
||||
case Set_kind:
|
||||
case Num_kind:
|
||||
case Str_kind:
|
||||
case Bytes_kind:
|
||||
case JoinedStr_kind:
|
||||
case FormattedValue_kind:
|
||||
expr_name = "literal";
|
||||
break;
|
||||
case NameConstant_kind:
|
||||
expr_name = "keyword";
|
||||
break;
|
||||
case Ellipsis_kind:
|
||||
expr_name = "Ellipsis";
|
||||
case Constant_kind: {
|
||||
PyObject *value = e->v.Constant.value;
|
||||
if (value == Py_None || value == Py_False || value == Py_True) {
|
||||
expr_name = "keyword";
|
||||
}
|
||||
else if (value == Py_Ellipsis) {
|
||||
expr_name = "Ellipsis";
|
||||
}
|
||||
else {
|
||||
expr_name = "literal";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Compare_kind:
|
||||
expr_name = "comparison";
|
||||
break;
|
||||
|
@ -2091,11 +2068,11 @@ ast_for_atom(struct compiling *c, const node *n)
|
|||
size_t len = strlen(s);
|
||||
if (len >= 4 && len <= 5) {
|
||||
if (!strcmp(s, "None"))
|
||||
return NameConstant(Py_None, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
return Constant(Py_None, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
if (!strcmp(s, "True"))
|
||||
return NameConstant(Py_True, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
return Constant(Py_True, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
if (!strcmp(s, "False"))
|
||||
return NameConstant(Py_False, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
return Constant(Py_False, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
}
|
||||
name = new_identifier(s, c);
|
||||
if (!name)
|
||||
|
@ -2144,10 +2121,10 @@ ast_for_atom(struct compiling *c, const node *n)
|
|||
Py_DECREF(pynum);
|
||||
return NULL;
|
||||
}
|
||||
return Num(pynum, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
return Constant(pynum, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
}
|
||||
case ELLIPSIS: /* Ellipsis */
|
||||
return Ellipsis(LINENO(n), n->n_col_offset, c->c_arena);
|
||||
return Constant(Py_Ellipsis, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
case LPAR: /* some parenthesized expressions */
|
||||
ch = CHILD(n, 1);
|
||||
|
||||
|
@ -4751,7 +4728,7 @@ typedef struct {
|
|||
expr_ty's, and then after that start dynamically allocating,
|
||||
doubling the number allocated each time. Note that the f-string
|
||||
f'{0}a{1}' contains 3 expr_ty's: 2 FormattedValue's, and one
|
||||
Str for the literal 'a'. So you add expr_ty's about twice as
|
||||
Constant for the literal 'a'. So you add expr_ty's about twice as
|
||||
fast as you add exressions in an f-string. */
|
||||
|
||||
Py_ssize_t allocated; /* Number we've allocated. */
|
||||
|
@ -4903,7 +4880,7 @@ FstringParser_Dealloc(FstringParser *state)
|
|||
ExprList_Dealloc(&state->expr_list);
|
||||
}
|
||||
|
||||
/* Make a Str node, but decref the PyUnicode object being added. */
|
||||
/* Make a Constant node, but decref the PyUnicode object being added. */
|
||||
static expr_ty
|
||||
make_str_node_and_del(PyObject **str, struct compiling *c, const node* n)
|
||||
{
|
||||
|
@ -4914,7 +4891,7 @@ make_str_node_and_del(PyObject **str, struct compiling *c, const node* n)
|
|||
Py_DECREF(s);
|
||||
return NULL;
|
||||
}
|
||||
return Str(s, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
return Constant(s, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
}
|
||||
|
||||
/* Add a non-f-string (that is, a regular literal string). str is
|
||||
|
@ -5002,11 +4979,11 @@ FstringParser_ConcatFstring(FstringParser *state, const char **str,
|
|||
break;
|
||||
|
||||
/* We know we have an expression. Convert any existing string
|
||||
to a Str node. */
|
||||
to a Constant node. */
|
||||
if (!state->last_str) {
|
||||
/* Do nothing. No previous literal. */
|
||||
} else {
|
||||
/* Convert the existing last_str literal to a Str node. */
|
||||
/* Convert the existing last_str literal to a Constant node. */
|
||||
expr_ty str = make_str_node_and_del(&state->last_str, c, n);
|
||||
if (!str || ExprList_Append(&state->expr_list, str) < 0)
|
||||
return -1;
|
||||
|
@ -5033,7 +5010,7 @@ FstringParser_ConcatFstring(FstringParser *state, const char **str,
|
|||
}
|
||||
|
||||
/* Convert the partial state reflected in last_str and expr_list to an
|
||||
expr_ty. The expr_ty can be a Str, or a JoinedStr. */
|
||||
expr_ty. The expr_ty can be a Constant, or a JoinedStr. */
|
||||
static expr_ty
|
||||
FstringParser_Finish(FstringParser *state, struct compiling *c,
|
||||
const node *n)
|
||||
|
@ -5055,7 +5032,7 @@ FstringParser_Finish(FstringParser *state, struct compiling *c,
|
|||
return make_str_node_and_del(&state->last_str, c, n);
|
||||
}
|
||||
|
||||
/* Create a Str node out of last_str, if needed. It will be the
|
||||
/* Create a Constant node out of last_str, if needed. It will be the
|
||||
last node in our expression list. */
|
||||
if (state->last_str) {
|
||||
expr_ty str = make_str_node_and_del(&state->last_str, c, n);
|
||||
|
@ -5206,9 +5183,9 @@ parsestr(struct compiling *c, const node *n, int *bytesmode, int *rawmode,
|
|||
|
||||
/* Accepts a STRING+ atom, and produces an expr_ty node. Run through
|
||||
each STRING atom, and process it as needed. For bytes, just
|
||||
concatenate them together, and the result will be a Bytes node. For
|
||||
concatenate them together, and the result will be a Constant node. For
|
||||
normal strings and f-strings, concatenate them together. The result
|
||||
will be a Str node if there were no f-strings; a FormattedValue
|
||||
will be a Constant node if there were no f-strings; a FormattedValue
|
||||
node if there's just an f-string (with no leading or trailing
|
||||
literals), or a JoinedStr node if there are multiple f-strings or
|
||||
any literals involved. */
|
||||
|
@ -5279,7 +5256,7 @@ parsestrplus(struct compiling *c, const node *n)
|
|||
/* Just return the bytes object and we're done. */
|
||||
if (PyArena_AddPyObject(c->c_arena, bytes_str) < 0)
|
||||
goto error;
|
||||
return Bytes(bytes_str, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
return Constant(bytes_str, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
}
|
||||
|
||||
/* We're not a bytes string, bytes_str should never have been set. */
|
||||
|
@ -5304,9 +5281,6 @@ _PyAST_GetDocString(asdl_seq *body)
|
|||
return NULL;
|
||||
}
|
||||
expr_ty e = st->v.Expr.value;
|
||||
if (e->kind == Str_kind) {
|
||||
return e->v.Str.s;
|
||||
}
|
||||
if (e->kind == Constant_kind && PyUnicode_CheckExact(e->v.Constant.value)) {
|
||||
return e->v.Constant.value;
|
||||
}
|
||||
|
|
|
@ -5,47 +5,6 @@
|
|||
#include "ast.h"
|
||||
|
||||
|
||||
/* TODO: is_const and get_const_value are copied from Python/compile.c.
|
||||
It should be deduped in the future. Maybe, we can include this file
|
||||
from compile.c?
|
||||
*/
|
||||
static int
|
||||
is_const(expr_ty e)
|
||||
{
|
||||
switch (e->kind) {
|
||||
case Constant_kind:
|
||||
case Num_kind:
|
||||
case Str_kind:
|
||||
case Bytes_kind:
|
||||
case Ellipsis_kind:
|
||||
case NameConstant_kind:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
get_const_value(expr_ty e)
|
||||
{
|
||||
switch (e->kind) {
|
||||
case Constant_kind:
|
||||
return e->v.Constant.value;
|
||||
case Num_kind:
|
||||
return e->v.Num.n;
|
||||
case Str_kind:
|
||||
return e->v.Str.s;
|
||||
case Bytes_kind:
|
||||
return e->v.Bytes.s;
|
||||
case Ellipsis_kind:
|
||||
return Py_Ellipsis;
|
||||
case NameConstant_kind:
|
||||
return e->v.NameConstant.value;
|
||||
default:
|
||||
Py_UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
make_const(expr_ty node, PyObject *val, PyArena *arena)
|
||||
{
|
||||
|
@ -81,7 +40,7 @@ fold_unaryop(expr_ty node, PyArena *arena, int optimize)
|
|||
{
|
||||
expr_ty arg = node->v.UnaryOp.operand;
|
||||
|
||||
if (!is_const(arg)) {
|
||||
if (arg->kind != Constant_kind) {
|
||||
/* Fold not into comparison */
|
||||
if (node->v.UnaryOp.op == Not && arg->kind == Compare_kind &&
|
||||
asdl_seq_LEN(arg->v.Compare.ops) == 1) {
|
||||
|
@ -123,7 +82,7 @@ fold_unaryop(expr_ty node, PyArena *arena, int optimize)
|
|||
[UAdd] = PyNumber_Positive,
|
||||
[USub] = PyNumber_Negative,
|
||||
};
|
||||
PyObject *newval = ops[node->v.UnaryOp.op](get_const_value(arg));
|
||||
PyObject *newval = ops[node->v.UnaryOp.op](arg->v.Constant.value);
|
||||
return make_const(node, newval, arena);
|
||||
}
|
||||
|
||||
|
@ -259,12 +218,12 @@ fold_binop(expr_ty node, PyArena *arena, int optimize)
|
|||
expr_ty lhs, rhs;
|
||||
lhs = node->v.BinOp.left;
|
||||
rhs = node->v.BinOp.right;
|
||||
if (!is_const(lhs) || !is_const(rhs)) {
|
||||
if (lhs->kind != Constant_kind || rhs->kind != Constant_kind) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
PyObject *lv = get_const_value(lhs);
|
||||
PyObject *rv = get_const_value(rhs);
|
||||
PyObject *lv = lhs->v.Constant.value;
|
||||
PyObject *rv = rhs->v.Constant.value;
|
||||
PyObject *newval;
|
||||
|
||||
switch (node->v.BinOp.op) {
|
||||
|
@ -316,7 +275,7 @@ make_const_tuple(asdl_seq *elts)
|
|||
{
|
||||
for (int i = 0; i < asdl_seq_LEN(elts); i++) {
|
||||
expr_ty e = (expr_ty)asdl_seq_GET(elts, i);
|
||||
if (!is_const(e)) {
|
||||
if (e->kind != Constant_kind) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -328,7 +287,7 @@ make_const_tuple(asdl_seq *elts)
|
|||
|
||||
for (int i = 0; i < asdl_seq_LEN(elts); i++) {
|
||||
expr_ty e = (expr_ty)asdl_seq_GET(elts, i);
|
||||
PyObject *v = get_const_value(e);
|
||||
PyObject *v = e->v.Constant.value;
|
||||
Py_INCREF(v);
|
||||
PyTuple_SET_ITEM(newval, i, v);
|
||||
}
|
||||
|
@ -357,16 +316,16 @@ fold_subscr(expr_ty node, PyArena *arena, int optimize)
|
|||
arg = node->v.Subscript.value;
|
||||
slice = node->v.Subscript.slice;
|
||||
if (node->v.Subscript.ctx != Load ||
|
||||
!is_const(arg) ||
|
||||
arg->kind != Constant_kind ||
|
||||
/* TODO: handle other types of slices */
|
||||
slice->kind != Index_kind ||
|
||||
!is_const(slice->v.Index.value))
|
||||
slice->v.Index.value->kind != Constant_kind)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
idx = slice->v.Index.value;
|
||||
newval = PyObject_GetItem(get_const_value(arg), get_const_value(idx));
|
||||
newval = PyObject_GetItem(arg->v.Constant.value, idx->v.Constant.value);
|
||||
return make_const(node, newval, arena);
|
||||
}
|
||||
|
||||
|
|
|
@ -567,8 +567,6 @@ append_fstring_element(_PyUnicodeWriter *writer, expr_ty e, bool is_format_spec)
|
|||
switch (e->kind) {
|
||||
case Constant_kind:
|
||||
return append_fstring_unicode(writer, e->v.Constant.value);
|
||||
case Str_kind:
|
||||
return append_fstring_unicode(writer, e->v.Str.s);
|
||||
case JoinedStr_kind:
|
||||
return append_joinedstr(writer, e, is_format_spec);
|
||||
case FormattedValue_kind:
|
||||
|
@ -690,13 +688,12 @@ static int
|
|||
append_ast_attribute(_PyUnicodeWriter *writer, expr_ty e)
|
||||
{
|
||||
const char *period;
|
||||
APPEND_EXPR(e->v.Attribute.value, PR_ATOM);
|
||||
expr_ty v = e->v.Attribute.value;
|
||||
APPEND_EXPR(v, PR_ATOM);
|
||||
|
||||
/* Special case: integers require a space for attribute access to be
|
||||
unambiguous. Floats and complex numbers don't but work with it, too. */
|
||||
if (e->v.Attribute.value->kind == Num_kind ||
|
||||
e->v.Attribute.value->kind == Constant_kind)
|
||||
{
|
||||
unambiguous. */
|
||||
if (v->kind == Constant_kind && PyLong_CheckExact(v->v.Constant.value)) {
|
||||
period = " .";
|
||||
}
|
||||
else {
|
||||
|
@ -841,21 +838,14 @@ append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, int level)
|
|||
case Call_kind:
|
||||
return append_ast_call(writer, e);
|
||||
case Constant_kind:
|
||||
if (e->v.Constant.value == Py_Ellipsis) {
|
||||
APPEND_STR_FINISH("...");
|
||||
}
|
||||
return append_repr(writer, e->v.Constant.value);
|
||||
case Num_kind:
|
||||
return append_repr(writer, e->v.Num.n);
|
||||
case Str_kind:
|
||||
return append_repr(writer, e->v.Str.s);
|
||||
case JoinedStr_kind:
|
||||
return append_joinedstr(writer, e, false);
|
||||
case FormattedValue_kind:
|
||||
return append_formattedvalue(writer, e, false);
|
||||
case Bytes_kind:
|
||||
return append_repr(writer, e->v.Bytes.s);
|
||||
case Ellipsis_kind:
|
||||
APPEND_STR_FINISH("...");
|
||||
case NameConstant_kind:
|
||||
return append_repr(writer, e->v.NameConstant.value);
|
||||
/* The following exprs can be assignment targets. */
|
||||
case Attribute_kind:
|
||||
return append_ast_attribute(writer, e);
|
||||
|
|
|
@ -1398,43 +1398,6 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute)
|
|||
} \
|
||||
}
|
||||
|
||||
static int
|
||||
is_const(expr_ty e)
|
||||
{
|
||||
switch (e->kind) {
|
||||
case Constant_kind:
|
||||
case Num_kind:
|
||||
case Str_kind:
|
||||
case Bytes_kind:
|
||||
case Ellipsis_kind:
|
||||
case NameConstant_kind:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
get_const_value(expr_ty e)
|
||||
{
|
||||
switch (e->kind) {
|
||||
case Constant_kind:
|
||||
return e->v.Constant.value;
|
||||
case Num_kind:
|
||||
return e->v.Num.n;
|
||||
case Str_kind:
|
||||
return e->v.Str.s;
|
||||
case Bytes_kind:
|
||||
return e->v.Bytes.s;
|
||||
case Ellipsis_kind:
|
||||
return Py_Ellipsis;
|
||||
case NameConstant_kind:
|
||||
return e->v.NameConstant.value;
|
||||
default:
|
||||
Py_UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
/* Search if variable annotations are present statically in a block. */
|
||||
|
||||
static int
|
||||
|
@ -2568,7 +2531,7 @@ static int
|
|||
compiler_return(struct compiler *c, stmt_ty s)
|
||||
{
|
||||
int preserve_tos = ((s->v.Return.value != NULL) &&
|
||||
!is_const(s->v.Return.value));
|
||||
(s->v.Return.value->kind != Constant_kind));
|
||||
if (c->u->u_ste->ste_type != FunctionBlock)
|
||||
return compiler_error(c, "'return' outside function");
|
||||
if (s->v.Return.value != NULL &&
|
||||
|
@ -3054,7 +3017,7 @@ compiler_visit_stmt_expr(struct compiler *c, expr_ty value)
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (is_const(value)) {
|
||||
if (value->kind == Constant_kind) {
|
||||
/* ignore constant statement */
|
||||
return 1;
|
||||
}
|
||||
|
@ -3502,7 +3465,7 @@ are_all_items_const(asdl_seq *seq, Py_ssize_t begin, Py_ssize_t end)
|
|||
Py_ssize_t i;
|
||||
for (i = begin; i < end; i++) {
|
||||
expr_ty key = (expr_ty)asdl_seq_GET(seq, i);
|
||||
if (key == NULL || !is_const(key))
|
||||
if (key == NULL || key->kind != Constant_kind)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
@ -3522,7 +3485,7 @@ compiler_subdict(struct compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end
|
|||
return 0;
|
||||
}
|
||||
for (i = begin; i < end; i++) {
|
||||
key = get_const_value((expr_ty)asdl_seq_GET(e->v.Dict.keys, i));
|
||||
key = ((expr_ty)asdl_seq_GET(e->v.Dict.keys, i))->v.Constant.value;
|
||||
Py_INCREF(key);
|
||||
PyTuple_SET_ITEM(keys, i - begin, key);
|
||||
}
|
||||
|
@ -4244,8 +4207,8 @@ compiler_visit_keyword(struct compiler *c, keyword_ty k)
|
|||
static int
|
||||
expr_constant(expr_ty e)
|
||||
{
|
||||
if (is_const(e)) {
|
||||
return PyObject_IsTrue(get_const_value(e));
|
||||
if (e->kind == Constant_kind) {
|
||||
return PyObject_IsTrue(e->v.Constant.value);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -4505,25 +4468,10 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
|
|||
case Constant_kind:
|
||||
ADDOP_LOAD_CONST(c, e->v.Constant.value);
|
||||
break;
|
||||
case Num_kind:
|
||||
ADDOP_LOAD_CONST(c, e->v.Num.n);
|
||||
break;
|
||||
case Str_kind:
|
||||
ADDOP_LOAD_CONST(c, e->v.Str.s);
|
||||
break;
|
||||
case JoinedStr_kind:
|
||||
return compiler_joined_str(c, e);
|
||||
case FormattedValue_kind:
|
||||
return compiler_formatted_value(c, e);
|
||||
case Bytes_kind:
|
||||
ADDOP_LOAD_CONST(c, e->v.Bytes.s);
|
||||
break;
|
||||
case Ellipsis_kind:
|
||||
ADDOP_LOAD_CONST(c, Py_Ellipsis);
|
||||
break;
|
||||
case NameConstant_kind:
|
||||
ADDOP_LOAD_CONST(c, e->v.NameConstant.value);
|
||||
break;
|
||||
/* The following exprs can be assignment targets. */
|
||||
case Attribute_kind:
|
||||
if (e->v.Attribute.ctx != AugStore)
|
||||
|
|
|
@ -1461,11 +1461,6 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
|
|||
VISIT_SEQ(st, expr, e->v.JoinedStr.values);
|
||||
break;
|
||||
case Constant_kind:
|
||||
case Num_kind:
|
||||
case Str_kind:
|
||||
case Bytes_kind:
|
||||
case Ellipsis_kind:
|
||||
case NameConstant_kind:
|
||||
/* Nothing to do here. */
|
||||
break;
|
||||
/* The following exprs can be assignment targets. */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue