Commit 10f8ce66 authored by Guido van Rossum's avatar Guido van Rossum Committed by Miss Islington (bot)

bpo-36280: Add Constant.kind field (GH-12295)



The value is a string for string and byte literals, None otherwise.
It is 'u' for u"..." literals, 'b' for b"..." literals, '' for "..." literals.
The 'r' (raw) prefix is ignored.
Does not apply to f-strings.

This appears sufficient to make mypy capable of using the stdlib ast module instead of typed_ast (assuming a mypy patch I'm working on).

WIP: I need to make the tests pass. @ilevkivskyi @serhiy-storchaka 



https://bugs.python.org/issue36280
parent 8b5bdda5
...@@ -338,6 +338,7 @@ struct _expr { ...@@ -338,6 +338,7 @@ struct _expr {
struct { struct {
constant value; constant value;
string kind;
} Constant; } Constant;
struct { struct {
...@@ -642,9 +643,9 @@ expr_ty _Py_FormattedValue(expr_ty value, int conversion, expr_ty format_spec, ...@@ -642,9 +643,9 @@ expr_ty _Py_FormattedValue(expr_ty value, int conversion, expr_ty format_spec,
#define JoinedStr(a0, a1, a2, a3, a4, a5) _Py_JoinedStr(a0, a1, a2, a3, a4, a5) #define JoinedStr(a0, a1, a2, a3, a4, a5) _Py_JoinedStr(a0, a1, a2, a3, a4, a5)
expr_ty _Py_JoinedStr(asdl_seq * values, int lineno, int col_offset, int expr_ty _Py_JoinedStr(asdl_seq * values, int lineno, int col_offset, int
end_lineno, int end_col_offset, PyArena *arena); end_lineno, int end_col_offset, PyArena *arena);
#define Constant(a0, a1, a2, a3, a4, a5) _Py_Constant(a0, a1, a2, a3, a4, a5) #define Constant(a0, a1, a2, a3, a4, a5, a6) _Py_Constant(a0, a1, a2, a3, a4, a5, a6)
expr_ty _Py_Constant(constant value, int lineno, int col_offset, int expr_ty _Py_Constant(constant value, string kind, int lineno, int col_offset,
end_lineno, int end_col_offset, PyArena *arena); int end_lineno, int end_col_offset, PyArena *arena);
#define Attribute(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Attribute(a0, a1, a2, a3, a4, a5, a6, a7) #define Attribute(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Attribute(a0, a1, a2, a3, a4, a5, a6, a7)
expr_ty _Py_Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int expr_ty _Py_Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int
lineno, int col_offset, int end_lineno, int lineno, int col_offset, int end_lineno, int
......
This diff is collapsed.
Add a kind field to ast.Constant. It is 'u' if the literal has a 'u' prefix
(i.e. a Python 2 style unicode literal), else None.
...@@ -78,7 +78,7 @@ module Python ...@@ -78,7 +78,7 @@ module Python
| Call(expr func, expr* args, keyword* keywords) | Call(expr func, expr* args, keyword* keywords)
| FormattedValue(expr value, int? conversion, expr? format_spec) | FormattedValue(expr value, int? conversion, expr? format_spec)
| JoinedStr(expr* values) | JoinedStr(expr* values)
| Constant(constant value) | Constant(constant value, string? kind)
-- the following expression can appear in assignment context -- the following expression can appear in assignment context
| Attribute(expr value, identifier attr, expr_context ctx) | Attribute(expr value, identifier attr, expr_context ctx)
......
...@@ -324,8 +324,10 @@ static char *JoinedStr_fields[]={ ...@@ -324,8 +324,10 @@ static char *JoinedStr_fields[]={
"values", "values",
}; };
static PyTypeObject *Constant_type; static PyTypeObject *Constant_type;
_Py_IDENTIFIER(kind);
static char *Constant_fields[]={ static char *Constant_fields[]={
"value", "value",
"kind",
}; };
static PyTypeObject *Attribute_type; static PyTypeObject *Attribute_type;
_Py_IDENTIFIER(attr); _Py_IDENTIFIER(attr);
...@@ -950,7 +952,7 @@ static int init_types(void) ...@@ -950,7 +952,7 @@ static int init_types(void)
if (!FormattedValue_type) return 0; if (!FormattedValue_type) return 0;
JoinedStr_type = make_type("JoinedStr", expr_type, JoinedStr_fields, 1); JoinedStr_type = make_type("JoinedStr", expr_type, JoinedStr_fields, 1);
if (!JoinedStr_type) return 0; 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; if (!Constant_type) return 0;
Attribute_type = make_type("Attribute", expr_type, Attribute_fields, 3); Attribute_type = make_type("Attribute", expr_type, Attribute_fields, 3);
if (!Attribute_type) return 0; if (!Attribute_type) return 0;
...@@ -2287,8 +2289,8 @@ JoinedStr(asdl_seq * values, int lineno, int col_offset, int end_lineno, int ...@@ -2287,8 +2289,8 @@ JoinedStr(asdl_seq * values, int lineno, int col_offset, int end_lineno, int
} }
expr_ty expr_ty
Constant(constant value, int lineno, int col_offset, int end_lineno, int Constant(constant value, string kind, int lineno, int col_offset, int
end_col_offset, PyArena *arena) end_lineno, int end_col_offset, PyArena *arena)
{ {
expr_ty p; expr_ty p;
if (!value) { if (!value) {
...@@ -2301,6 +2303,7 @@ Constant(constant value, int lineno, int col_offset, int end_lineno, int ...@@ -2301,6 +2303,7 @@ Constant(constant value, int lineno, int col_offset, int end_lineno, int
return NULL; return NULL;
p->kind = Constant_kind; p->kind = Constant_kind;
p->v.Constant.value = value; p->v.Constant.value = value;
p->v.Constant.kind = kind;
p->lineno = lineno; p->lineno = lineno;
p->col_offset = col_offset; p->col_offset = col_offset;
p->end_lineno = end_lineno; p->end_lineno = end_lineno;
...@@ -3507,6 +3510,11 @@ ast2obj_expr(void* _o) ...@@ -3507,6 +3510,11 @@ ast2obj_expr(void* _o)
if (_PyObject_SetAttrId(result, &PyId_value, value) == -1) if (_PyObject_SetAttrId(result, &PyId_value, value) == -1)
goto failed; goto failed;
Py_DECREF(value); 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; break;
case Attribute_kind: case Attribute_kind:
result = PyType_GenericNew(Attribute_type, NULL, NULL); result = PyType_GenericNew(Attribute_type, NULL, NULL);
...@@ -7224,6 +7232,7 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena) ...@@ -7224,6 +7232,7 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena)
} }
if (isinstance) { if (isinstance) {
constant value; constant value;
string kind;
if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) { if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) {
return 1; return 1;
...@@ -7238,8 +7247,21 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena) ...@@ -7238,8 +7247,21 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena)
if (res != 0) goto failed; if (res != 0) goto failed;
Py_CLEAR(tmp); Py_CLEAR(tmp);
} }
*out = Constant(value, lineno, col_offset, end_lineno, end_col_offset, if (_PyObject_LookupAttrId(obj, &PyId_kind, &tmp) < 0) {
arena); 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; if (*out == NULL) goto failed;
return 0; return 0;
} }
......
...@@ -2313,13 +2313,13 @@ ast_for_atom(struct compiling *c, const node *n) ...@@ -2313,13 +2313,13 @@ ast_for_atom(struct compiling *c, const node *n)
size_t len = strlen(s); size_t len = strlen(s);
if (len >= 4 && len <= 5) { if (len >= 4 && len <= 5) {
if (!strcmp(s, "None")) 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); n->n_end_lineno, n->n_end_col_offset, c->c_arena);
if (!strcmp(s, "True")) 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); n->n_end_lineno, n->n_end_col_offset, c->c_arena);
if (!strcmp(s, "False")) 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); n->n_end_lineno, n->n_end_col_offset, c->c_arena);
} }
name = new_identifier(s, c); name = new_identifier(s, c);
...@@ -2374,11 +2374,11 @@ ast_for_atom(struct compiling *c, const node *n) ...@@ -2374,11 +2374,11 @@ ast_for_atom(struct compiling *c, const node *n)
Py_DECREF(pynum); Py_DECREF(pynum);
return NULL; 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); n->n_end_lineno, n->n_end_col_offset, c->c_arena);
} }
case ELLIPSIS: /* Ellipsis */ 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); n->n_end_lineno, n->n_end_col_offset, c->c_arena);
case LPAR: /* some parenthesized expressions */ case LPAR: /* some parenthesized expressions */
ch = CHILD(n, 1); ch = CHILD(n, 1);
...@@ -5388,18 +5388,57 @@ FstringParser_Dealloc(FstringParser *state) ...@@ -5388,18 +5388,57 @@ FstringParser_Dealloc(FstringParser *state)
ExprList_Dealloc(&state->expr_list); 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. */ /* Make a Constant node, but decref the PyUnicode object being added. */
static expr_ty static expr_ty
make_str_node_and_del(PyObject **str, struct compiling *c, const node* n) make_str_node_and_del(PyObject **str, struct compiling *c, const node* n)
{ {
PyObject *s = *str; PyObject *s = *str;
PyObject *kind = NULL;
*str = NULL; *str = NULL;
assert(PyUnicode_CheckExact(s)); assert(PyUnicode_CheckExact(s));
if (PyArena_AddPyObject(c->c_arena, s) < 0) { if (PyArena_AddPyObject(c->c_arena, s) < 0) {
Py_DECREF(s); Py_DECREF(s);
return NULL; 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); n->n_end_lineno, n->n_end_col_offset, c->c_arena);
} }
...@@ -5774,7 +5813,7 @@ parsestrplus(struct compiling *c, const node *n) ...@@ -5774,7 +5813,7 @@ parsestrplus(struct compiling *c, const node *n)
/* Just return the bytes object and we're done. */ /* Just return the bytes object and we're done. */
if (PyArena_AddPyObject(c->c_arena, bytes_str) < 0) if (PyArena_AddPyObject(c->c_arena, bytes_str) < 0)
goto error; 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); n->n_end_lineno, n->n_end_col_offset, c->c_arena);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment