diff options
author | Pablo Galindo <Pablogsal@gmail.com> | 2020-04-01 23:47:39 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-01 23:47:39 (GMT) |
commit | 168660b547d5f683c5d3c60447cfa8c6d620efc3 (patch) | |
tree | e57909715a435ccb1699af5670b3a3319636317e /Python | |
parent | 65a796e5272f61b42792d3a8c69686558c1872c5 (diff) | |
download | cpython-168660b547d5f683c5d3c60447cfa8c6d620efc3.zip cpython-168660b547d5f683c5d3c60447cfa8c6d620efc3.tar.gz cpython-168660b547d5f683c5d3c60447cfa8c6d620efc3.tar.bz2 |
bpo-40141: Add line and column information to ast.keyword nodes (GH-19283)
Diffstat (limited to 'Python')
-rw-r--r-- | Python/Python-ast.c | 103 | ||||
-rw-r--r-- | Python/ast.c | 7 |
2 files changed, 105 insertions, 5 deletions
diff --git a/Python/Python-ast.c b/Python/Python-ast.c index c7c7fda..488276a 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -1060,6 +1060,12 @@ static const char * const arg_fields[]={ "type_comment", }; static PyObject* ast2obj_keyword(void*); +static const char * const keyword_attributes[] = { + "lineno", + "col_offset", + "end_lineno", + "end_col_offset", +}; static const char * const keyword_fields[]={ "arg", "value", @@ -1985,9 +1991,14 @@ static int init_types(void) 2, "keyword(identifier? arg, expr value)"); if (!state->keyword_type) return 0; - if (!add_attributes(state->keyword_type, NULL, 0)) return 0; + if (!add_attributes(state->keyword_type, keyword_attributes, 4)) return 0; if (PyObject_SetAttr(state->keyword_type, state->arg, Py_None) == -1) return 0; + if (PyObject_SetAttr(state->keyword_type, state->end_lineno, Py_None) == -1) + return 0; + if (PyObject_SetAttr(state->keyword_type, state->end_col_offset, Py_None) + == -1) + return 0; state->alias_type = make_type("alias", state->AST_type, alias_fields, 2, "alias(identifier name, identifier? asname)"); if (!state->alias_type) return 0; @@ -3422,7 +3433,8 @@ arg(identifier arg, expr_ty annotation, string type_comment, int lineno, int } keyword_ty -keyword(identifier arg, expr_ty value, PyArena *arena) +keyword(identifier arg, expr_ty value, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) { keyword_ty p; if (!value) { @@ -3435,6 +3447,10 @@ keyword(identifier arg, expr_ty value, PyArena *arena) return NULL; p->arg = arg; p->value = value; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; return p; } @@ -4954,6 +4970,27 @@ ast2obj_keyword(void* _o) if (PyObject_SetAttr(result, astmodulestate_global->value, value) == -1) goto failed; Py_DECREF(value); + value = ast2obj_int(o->lineno); + if (!value) goto failed; + if (PyObject_SetAttr(result, astmodulestate_global->lineno, value) < 0) + goto failed; + Py_DECREF(value); + value = ast2obj_int(o->col_offset); + if (!value) goto failed; + if (PyObject_SetAttr(result, astmodulestate_global->col_offset, value) < 0) + goto failed; + Py_DECREF(value); + value = ast2obj_int(o->end_lineno); + if (!value) goto failed; + if (PyObject_SetAttr(result, astmodulestate_global->end_lineno, value) < 0) + goto failed; + Py_DECREF(value); + value = ast2obj_int(o->end_col_offset); + if (!value) goto failed; + if (PyObject_SetAttr(result, astmodulestate_global->end_col_offset, value) + < 0) + goto failed; + Py_DECREF(value); return result; failed: Py_XDECREF(value); @@ -9628,6 +9665,10 @@ obj2ast_keyword(PyObject* obj, keyword_ty* out, PyArena* arena) PyObject* tmp = NULL; identifier arg; expr_ty value; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; if (_PyObject_LookupAttr(obj, astmodulestate_global->arg, &tmp) < 0) { return 1; @@ -9655,7 +9696,63 @@ obj2ast_keyword(PyObject* obj, keyword_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = keyword(arg, value, arena); + if (_PyObject_LookupAttr(obj, astmodulestate_global->lineno, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from keyword"); + return 1; + } + else { + int res; + res = obj2ast_int(tmp, &lineno, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, astmodulestate_global->col_offset, &tmp) < 0) + { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from keyword"); + return 1; + } + else { + int res; + res = obj2ast_int(tmp, &col_offset, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, astmodulestate_global->end_lineno, &tmp) < 0) + { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + end_lineno = 0; + } + else { + int res; + res = obj2ast_int(tmp, &end_lineno, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, astmodulestate_global->end_col_offset, &tmp) + < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + end_col_offset = 0; + } + else { + int res; + res = obj2ast_int(tmp, &end_col_offset, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = keyword(arg, value, lineno, col_offset, end_lineno, end_col_offset, + arena); return 0; failed: Py_XDECREF(tmp); diff --git a/Python/ast.c b/Python/ast.c index fb23c02..550ee03 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -3013,7 +3013,8 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func, e = ast_for_expr(c, CHILD(ch, 1)); if (!e) return NULL; - kw = keyword(NULL, e, c->c_arena); + kw = keyword(NULL, e, chch->n_lineno, chch->n_col_offset, + e->end_lineno, e->end_col_offset, c->c_arena); asdl_seq_SET(keywords, nkeywords++, kw); ndoublestars++; } @@ -3103,7 +3104,9 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func, e = ast_for_expr(c, CHILD(ch, 2)); if (!e) return NULL; - kw = keyword(key, e, c->c_arena); + kw = keyword(key, e, chch->n_lineno, chch->n_col_offset, + chch->n_end_lineno, chch->n_end_col_offset, c->c_arena); + if (!kw) return NULL; asdl_seq_SET(keywords, nkeywords++, kw); |