From 95b6acf951fa7f503a3cc5ce7d969d7bcf2f95c9 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 30 Oct 2018 13:16:02 +0200 Subject: bpo-34876: Change the lineno of the AST for decorated function and class. (GH-9731) It was overridden by the lineno of the first decorator. Now it is the lineno of 'def' or 'class'. --- Python/compile.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 11958d3841..45a8c573a5 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1950,6 +1950,7 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async) Py_ssize_t i, funcflags; int annotations; int scope_type; + int firstlineno; if (is_async) { assert(s->kind == AsyncFunctionDef_kind); @@ -1976,6 +1977,11 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async) if (!compiler_decorators(c, decos)) return 0; + firstlineno = s->lineno; + if (asdl_seq_LEN(decos)) { + firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno; + } + funcflags = compiler_default_arguments(c, args); if (funcflags == -1) { return 0; @@ -1989,7 +1995,7 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async) funcflags |= 0x04; } - if (!compiler_enter_scope(c, name, scope_type, (void *)s, s->lineno)) { + if (!compiler_enter_scope(c, name, scope_type, (void *)s, firstlineno)) { return 0; } @@ -2032,12 +2038,17 @@ compiler_class(struct compiler *c, stmt_ty s) { PyCodeObject *co; PyObject *str; - int i; + int i, firstlineno; asdl_seq* decos = s->v.ClassDef.decorator_list; if (!compiler_decorators(c, decos)) return 0; + firstlineno = s->lineno; + if (asdl_seq_LEN(decos)) { + firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno; + } + /* ultimately generate code for: = __build_class__(, , *, **) where: @@ -2052,7 +2063,7 @@ compiler_class(struct compiler *c, stmt_ty s) /* 1. compile the class body into a code object */ if (!compiler_enter_scope(c, s->v.ClassDef.name, - COMPILER_SCOPE_CLASS, (void *)s, s->lineno)) + COMPILER_SCOPE_CLASS, (void *)s, firstlineno)) return 0; /* this block represents what we do in the new scope */ { -- cgit v1.2.1