Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f9827ea

Browse files
committed
Issue #25555: Fix parser and AST: fill lineno and col_offset of "arg" node when
compiling AST from Python objects.
1 parent 8263981 commit f9827ea

5 files changed

Lines changed: 48 additions & 12 deletions

File tree

Include/Python-ast.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -585,8 +585,9 @@ excepthandler_ty _Py_ExceptHandler(expr_ty type, identifier name, asdl_seq *
585585
arguments_ty _Py_arguments(asdl_seq * args, arg_ty vararg, asdl_seq *
586586
kwonlyargs, asdl_seq * kw_defaults, arg_ty kwarg,
587587
asdl_seq * defaults, PyArena *arena);
588-
#define arg(a0, a1, a2) _Py_arg(a0, a1, a2)
589-
arg_ty _Py_arg(identifier arg, expr_ty annotation, PyArena *arena);
588+
#define arg(a0, a1, a2, a3, a4) _Py_arg(a0, a1, a2, a3, a4)
589+
arg_ty _Py_arg(identifier arg, expr_ty annotation, int lineno, int col_offset,
590+
PyArena *arena);
590591
#define keyword(a0, a1, a2) _Py_keyword(a0, a1, a2)
591592
keyword_ty _Py_keyword(identifier arg, expr_ty value, PyArena *arena);
592593
#define alias(a0, a1, a2) _Py_alias(a0, a1, a2)

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ Release date: TBA
1111
Core and Builtins
1212
-----------------
1313

14+
- Issue #25555: Fix parser and AST: fill lineno and col_offset of "arg" node
15+
when compiling AST from Python objects.
16+
1417
- Issue #24802: Avoid buffer overreads when int(), float(), compile(), exec()
1518
and eval() are passed bytes-like objects. These objects are not
1619
necessarily terminated by a null byte, but the functions assumed they were.

Parser/asdl_c.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,9 @@ def emit_function(self, name, ctype, args, attrs, union=True):
275275

276276
def visitProduct(self, prod, name):
277277
self.emit_function(name, get_c_type(name),
278-
self.get_args(prod.fields), [], union=False)
278+
self.get_args(prod.fields),
279+
self.get_args(prod.attributes),
280+
union=False)
279281

280282

281283
class FunctionVisitor(PrototypeVisitor):
@@ -329,7 +331,8 @@ def emit(s, depth=0, reflow=True):
329331
self.emit(s, depth, reflow)
330332
for argtype, argname, opt in args:
331333
emit("p->%s = %s;" % (argname, argname), 1)
332-
assert not attrs
334+
for argtype, argname, opt in attrs:
335+
emit("p->%s = %s;" % (argname, argname), 1)
333336

334337

335338
class PickleVisitor(EmitVisitor):
@@ -452,10 +455,15 @@ def visitProduct(self, prod, name):
452455
self.emit("PyObject* tmp = NULL;", 1)
453456
for f in prod.fields:
454457
self.visitFieldDeclaration(f, name, prod=prod, depth=1)
458+
for a in prod.attributes:
459+
self.visitFieldDeclaration(a, name, prod=prod, depth=1)
455460
self.emit("", 0)
456461
for f in prod.fields:
457462
self.visitField(f, name, prod=prod, depth=1)
463+
for a in prod.attributes:
464+
self.visitField(a, name, prod=prod, depth=1)
458465
args = [f.name for f in prod.fields]
466+
args.extend([a.name for a in prod.attributes])
459467
self.emit("*out = %s(%s);" % (name, self.buildArgs(args)), 1)
460468
self.emit("return 0;", 1)
461469
self.emit("failed:", 0)

Python/Python-ast.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2372,7 +2372,8 @@ arguments(asdl_seq * args, arg_ty vararg, asdl_seq * kwonlyargs, asdl_seq *
23722372
}
23732373

23742374
arg_ty
2375-
arg(identifier arg, expr_ty annotation, PyArena *arena)
2375+
arg(identifier arg, expr_ty annotation, int lineno, int col_offset, PyArena
2376+
*arena)
23762377
{
23772378
arg_ty p;
23782379
if (!arg) {
@@ -2385,6 +2386,8 @@ arg(identifier arg, expr_ty annotation, PyArena *arena)
23852386
return NULL;
23862387
p->arg = arg;
23872388
p->annotation = annotation;
2389+
p->lineno = lineno;
2390+
p->col_offset = col_offset;
23882391
return p;
23892392
}
23902393

@@ -7086,6 +7089,8 @@ obj2ast_arg(PyObject* obj, arg_ty* out, PyArena* arena)
70867089
PyObject* tmp = NULL;
70877090
identifier arg;
70887091
expr_ty annotation;
7092+
int lineno;
7093+
int col_offset;
70897094

70907095
if (_PyObject_HasAttrId(obj, &PyId_arg)) {
70917096
int res;
@@ -7108,7 +7113,29 @@ obj2ast_arg(PyObject* obj, arg_ty* out, PyArena* arena)
71087113
} else {
71097114
annotation = NULL;
71107115
}
7111-
*out = arg(arg, annotation, arena);
7116+
if (_PyObject_HasAttrId(obj, &PyId_lineno)) {
7117+
int res;
7118+
tmp = _PyObject_GetAttrId(obj, &PyId_lineno);
7119+
if (tmp == NULL) goto failed;
7120+
res = obj2ast_int(tmp, &lineno, arena);
7121+
if (res != 0) goto failed;
7122+
Py_CLEAR(tmp);
7123+
} else {
7124+
PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from arg");
7125+
return 1;
7126+
}
7127+
if (_PyObject_HasAttrId(obj, &PyId_col_offset)) {
7128+
int res;
7129+
tmp = _PyObject_GetAttrId(obj, &PyId_col_offset);
7130+
if (tmp == NULL) goto failed;
7131+
res = obj2ast_int(tmp, &col_offset, arena);
7132+
if (res != 0) goto failed;
7133+
Py_CLEAR(tmp);
7134+
} else {
7135+
PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from arg");
7136+
return 1;
7137+
}
7138+
*out = arg(arg, annotation, lineno, col_offset, arena);
71127139
return 0;
71137140
failed:
71147141
Py_XDECREF(tmp);

Python/ast.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,11 +1173,9 @@ ast_for_arg(struct compiling *c, const node *n)
11731173
return NULL;
11741174
}
11751175

1176-
ret = arg(name, annotation, c->c_arena);
1176+
ret = arg(name, annotation, LINENO(n), n->n_col_offset, c->c_arena);
11771177
if (!ret)
11781178
return NULL;
1179-
ret->lineno = LINENO(n);
1180-
ret->col_offset = n->n_col_offset;
11811179
return ret;
11821180
}
11831181

@@ -1233,11 +1231,10 @@ handle_keywordonly_args(struct compiling *c, const node *n, int start,
12331231
goto error;
12341232
if (forbidden_name(c, argname, ch, 0))
12351233
goto error;
1236-
arg = arg(argname, annotation, c->c_arena);
1234+
arg = arg(argname, annotation, LINENO(ch), ch->n_col_offset,
1235+
c->c_arena);
12371236
if (!arg)
12381237
goto error;
1239-
arg->lineno = LINENO(ch);
1240-
arg->col_offset = ch->n_col_offset;
12411238
asdl_seq_SET(kwonlyargs, j++, arg);
12421239
i += 2; /* the name and the comma */
12431240
break;

0 commit comments

Comments
 (0)