summaryrefslogtreecommitdiff
path: root/Python
diff options
context:
space:
mode:
Diffstat (limited to 'Python')
-rw-r--r--Python/Python-ast.c32
-rw-r--r--Python/ast.c53
2 files changed, 73 insertions, 12 deletions
diff --git a/Python/Python-ast.c b/Python/Python-ast.c
index 0411f9f07f..d0416eb639 100644
--- a/Python/Python-ast.c
+++ b/Python/Python-ast.c
@@ -324,8 +324,10 @@ static char *JoinedStr_fields[]={
"values",
};
static PyTypeObject *Constant_type;
+_Py_IDENTIFIER(kind);
static char *Constant_fields[]={
"value",
+ "kind",
};
static PyTypeObject *Attribute_type;
_Py_IDENTIFIER(attr);
@@ -950,7 +952,7 @@ static int init_types(void)
if (!FormattedValue_type) return 0;
JoinedStr_type = make_type("JoinedStr", expr_type, JoinedStr_fields, 1);
if (!JoinedStr_type) return 0;
- Constant_type = make_type("Constant", expr_type, Constant_fields, 1);
+ Constant_type = make_type("Constant", expr_type, Constant_fields, 2);
if (!Constant_type) return 0;
Attribute_type = make_type("Attribute", expr_type, Attribute_fields, 3);
if (!Attribute_type) return 0;
@@ -2287,8 +2289,8 @@ JoinedStr(asdl_seq * values, int lineno, int col_offset, int end_lineno, int
}
expr_ty
-Constant(constant value, int lineno, int col_offset, int end_lineno, int
- end_col_offset, PyArena *arena)
+Constant(constant value, string kind, int lineno, int col_offset, int
+ end_lineno, int end_col_offset, PyArena *arena)
{
expr_ty p;
if (!value) {
@@ -2301,6 +2303,7 @@ Constant(constant value, int lineno, int col_offset, int end_lineno, int
return NULL;
p->kind = Constant_kind;
p->v.Constant.value = value;
+ p->v.Constant.kind = kind;
p->lineno = lineno;
p->col_offset = col_offset;
p->end_lineno = end_lineno;
@@ -3507,6 +3510,11 @@ ast2obj_expr(void* _o)
if (_PyObject_SetAttrId(result, &PyId_value, value) == -1)
goto failed;
Py_DECREF(value);
+ value = ast2obj_string(o->v.Constant.kind);
+ if (!value) goto failed;
+ if (_PyObject_SetAttrId(result, &PyId_kind, value) == -1)
+ goto failed;
+ Py_DECREF(value);
break;
case Attribute_kind:
result = PyType_GenericNew(Attribute_type, NULL, NULL);
@@ -7224,6 +7232,7 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena)
}
if (isinstance) {
constant value;
+ string kind;
if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) {
return 1;
@@ -7238,8 +7247,21 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena)
if (res != 0) goto failed;
Py_CLEAR(tmp);
}
- *out = Constant(value, lineno, col_offset, end_lineno, end_col_offset,
- arena);
+ if (_PyObject_LookupAttrId(obj, &PyId_kind, &tmp) < 0) {
+ return 1;
+ }
+ if (tmp == NULL || tmp == Py_None) {
+ Py_CLEAR(tmp);
+ kind = NULL;
+ }
+ else {
+ int res;
+ res = obj2ast_string(tmp, &kind, arena);
+ if (res != 0) goto failed;
+ Py_CLEAR(tmp);
+ }
+ *out = Constant(value, kind, lineno, col_offset, end_lineno,
+ end_col_offset, arena);
if (*out == NULL) goto failed;
return 0;
}
diff --git a/Python/ast.c b/Python/ast.c
index d4ee1b351f..971b8ddc8c 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -2313,13 +2313,13 @@ ast_for_atom(struct compiling *c, const node *n)
size_t len = strlen(s);
if (len >= 4 && len <= 5) {
if (!strcmp(s, "None"))
- return Constant(Py_None, LINENO(n), n->n_col_offset,
+ return Constant(Py_None, NULL, LINENO(n), n->n_col_offset,
n->n_end_lineno, n->n_end_col_offset, c->c_arena);
if (!strcmp(s, "True"))
- return Constant(Py_True, LINENO(n), n->n_col_offset,
+ return Constant(Py_True, NULL, LINENO(n), n->n_col_offset,
n->n_end_lineno, n->n_end_col_offset, c->c_arena);
if (!strcmp(s, "False"))
- return Constant(Py_False, LINENO(n), n->n_col_offset,
+ return Constant(Py_False, NULL, LINENO(n), n->n_col_offset,
n->n_end_lineno, n->n_end_col_offset, c->c_arena);
}
name = new_identifier(s, c);
@@ -2374,11 +2374,11 @@ ast_for_atom(struct compiling *c, const node *n)
Py_DECREF(pynum);
return NULL;
}
- return Constant(pynum, LINENO(n), n->n_col_offset,
+ return Constant(pynum, NULL, LINENO(n), n->n_col_offset,
n->n_end_lineno, n->n_end_col_offset, c->c_arena);
}
case ELLIPSIS: /* Ellipsis */
- return Constant(Py_Ellipsis, LINENO(n), n->n_col_offset,
+ return Constant(Py_Ellipsis, NULL, LINENO(n), n->n_col_offset,
n->n_end_lineno, n->n_end_col_offset, c->c_arena);
case LPAR: /* some parenthesized expressions */
ch = CHILD(n, 1);
@@ -5388,18 +5388,57 @@ FstringParser_Dealloc(FstringParser *state)
ExprList_Dealloc(&state->expr_list);
}
+/* Constants for the following */
+static PyObject *u_kind;
+
+/* Compute 'kind' field for string Constant (either 'u' or None) */
+static PyObject *
+make_kind(struct compiling *c, const node *n)
+{
+ char *s = NULL;
+ PyObject *kind = NULL;
+
+ /* Find the first string literal, if any */
+ while (TYPE(n) != STRING) {
+ if (NCH(n) == 0)
+ return NULL;
+ n = CHILD(n, 0);
+ }
+ REQ(n, STRING);
+
+ /* If it starts with 'u', return a PyUnicode "u" string */
+ s = STR(n);
+ if (s && *s == 'u') {
+ if (!u_kind) {
+ u_kind = PyUnicode_InternFromString("u");
+ if (!u_kind)
+ return NULL;
+ }
+ kind = u_kind;
+ if (PyArena_AddPyObject(c->c_arena, kind) < 0) {
+ return NULL;
+ }
+ Py_INCREF(kind);
+ }
+ return kind;
+}
+
/* Make a Constant node, but decref the PyUnicode object being added. */
static expr_ty
make_str_node_and_del(PyObject **str, struct compiling *c, const node* n)
{
PyObject *s = *str;
+ PyObject *kind = NULL;
*str = NULL;
assert(PyUnicode_CheckExact(s));
if (PyArena_AddPyObject(c->c_arena, s) < 0) {
Py_DECREF(s);
return NULL;
}
- return Constant(s, LINENO(n), n->n_col_offset,
+ kind = make_kind(c, n);
+ if (kind == NULL && PyErr_Occurred())
+ return NULL;
+ return Constant(s, kind, LINENO(n), n->n_col_offset,
n->n_end_lineno, n->n_end_col_offset, c->c_arena);
}
@@ -5774,7 +5813,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 Constant(bytes_str, LINENO(n), n->n_col_offset,
+ return Constant(bytes_str, NULL, LINENO(n), n->n_col_offset,
n->n_end_lineno, n->n_end_col_offset, c->c_arena);
}