Skip to content

Commit 040c0a5

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 db7d672 commit 040c0a5

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
@@ -602,8 +602,9 @@ excepthandler_ty _Py_ExceptHandler(expr_ty type, identifier name, asdl_seq *
602602
arguments_ty _Py_arguments(asdl_seq * args, arg_ty vararg, asdl_seq *
603603
kwonlyargs, asdl_seq * kw_defaults, arg_ty kwarg,
604604
asdl_seq * defaults, PyArena *arena);
605-
#define arg(a0, a1, a2) _Py_arg(a0, a1, a2)
606-
arg_ty _Py_arg(identifier arg, expr_ty annotation, PyArena *arena);
605+
#define arg(a0, a1, a2, a3, a4) _Py_arg(a0, a1, a2, a3, a4)
606+
arg_ty _Py_arg(identifier arg, expr_ty annotation, int lineno, int col_offset,
607+
PyArena *arena);
607608
#define keyword(a0, a1, a2) _Py_keyword(a0, a1, a2)
608609
keyword_ty _Py_keyword(identifier arg, expr_ty value, PyArena *arena);
609610
#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
@@ -10,6 +10,9 @@ Release date: XXXX-XX-XX
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #25555: Fix parser and AST: fill lineno and col_offset of "arg" node
14+
when compiling AST from Python objects.
15+
1316
- Issue #24726: Fixed a crash and leaking NULL in repr() of OrderedDict that
1417
was mutated by direct calls of dict methods.
1518

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
@@ -2425,7 +2425,8 @@ arguments(asdl_seq * args, arg_ty vararg, asdl_seq * kwonlyargs, asdl_seq *
24252425
}
24262426

24272427
arg_ty
2428-
arg(identifier arg, expr_ty annotation, PyArena *arena)
2428+
arg(identifier arg, expr_ty annotation, int lineno, int col_offset, PyArena
2429+
*arena)
24292430
{
24302431
arg_ty p;
24312432
if (!arg) {
@@ -2438,6 +2439,8 @@ arg(identifier arg, expr_ty annotation, PyArena *arena)
24382439
return NULL;
24392440
p->arg = arg;
24402441
p->annotation = annotation;
2442+
p->lineno = lineno;
2443+
p->col_offset = col_offset;
24412444
return p;
24422445
}
24432446

@@ -7247,6 +7250,8 @@ obj2ast_arg(PyObject* obj, arg_ty* out, PyArena* arena)
72477250
PyObject* tmp = NULL;
72487251
identifier arg;
72497252
expr_ty annotation;
7253+
int lineno;
7254+
int col_offset;
72507255

72517256
if (_PyObject_HasAttrId(obj, &PyId_arg)) {
72527257
int res;
@@ -7269,7 +7274,29 @@ obj2ast_arg(PyObject* obj, arg_ty* out, PyArena* arena)
72697274
} else {
72707275
annotation = NULL;
72717276
}
7272-
*out = arg(arg, annotation, arena);
7277+
if (_PyObject_HasAttrId(obj, &PyId_lineno)) {
7278+
int res;
7279+
tmp = _PyObject_GetAttrId(obj, &PyId_lineno);
7280+
if (tmp == NULL) goto failed;
7281+
res = obj2ast_int(tmp, &lineno, arena);
7282+
if (res != 0) goto failed;
7283+
Py_CLEAR(tmp);
7284+
} else {
7285+
PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from arg");
7286+
return 1;
7287+
}
7288+
if (_PyObject_HasAttrId(obj, &PyId_col_offset)) {
7289+
int res;
7290+
tmp = _PyObject_GetAttrId(obj, &PyId_col_offset);
7291+
if (tmp == NULL) goto failed;
7292+
res = obj2ast_int(tmp, &col_offset, arena);
7293+
if (res != 0) goto failed;
7294+
Py_CLEAR(tmp);
7295+
} else {
7296+
PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from arg");
7297+
return 1;
7298+
}
7299+
*out = arg(arg, annotation, lineno, col_offset, arena);
72737300
return 0;
72747301
failed:
72757302
Py_XDECREF(tmp);

Python/ast.c

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

1184-
ret = arg(name, annotation, c->c_arena);
1184+
ret = arg(name, annotation, LINENO(n), n->n_col_offset, c->c_arena);
11851185
if (!ret)
11861186
return NULL;
1187-
ret->lineno = LINENO(n);
1188-
ret->col_offset = n->n_col_offset;
11891187
return ret;
11901188
}
11911189

@@ -1241,11 +1239,10 @@ handle_keywordonly_args(struct compiling *c, const node *n, int start,
12411239
goto error;
12421240
if (forbidden_name(c, argname, ch, 0))
12431241
goto error;
1244-
arg = arg(argname, annotation, c->c_arena);
1242+
arg = arg(argname, annotation, LINENO(ch), ch->n_col_offset,
1243+
c->c_arena);
12451244
if (!arg)
12461245
goto error;
1247-
arg->lineno = LINENO(ch);
1248-
arg->col_offset = ch->n_col_offset;
12491246
asdl_seq_SET(kwonlyargs, j++, arg);
12501247
i += 2; /* the name and the comma */
12511248
break;

0 commit comments

Comments
 (0)