diff options
| author | Brandt Bucher <brandtbucher@microsoft.com> | 2022-07-23 00:31:06 (GMT) |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-07-23 00:31:06 (GMT) |
| commit | 064462a719509c1382207387e3a3ef187f7b55bf (patch) | |
| tree | 45f7c4cb8c04a1fab3c824c9c22bdf92fed56be5 /Python | |
| parent | bbdacb402bb441972312372f7b2104a51c32350e (diff) | |
| download | cpython-064462a719509c1382207387e3a3ef187f7b55bf.zip cpython-064462a719509c1382207387e3a3ef187f7b55bf.tar.gz cpython-064462a719509c1382207387e3a3ef187f7b55bf.tar.bz2 | |
[3.11] GH-94036: Fix more attribute location quirks (GH-95028) (GH-95156)
(cherry picked from commit 900bfc53cb133e8bc2b122362ec04256f623d5b0)
Diffstat (limited to 'Python')
| -rw-r--r-- | Python/compile.c | 43 |
1 files changed, 23 insertions, 20 deletions
diff --git a/Python/compile.c b/Python/compile.c index 8895ac7..32fd58e 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -4783,19 +4783,29 @@ is_import_originated(struct compiler *c, expr_ty e) return flags & DEF_IMPORT; } +// If an attribute access spans multiple lines, update the current start +// location to point to the attribute name. static void -update_location_to_match_attr(struct compiler *c, expr_ty meth) +update_start_location_to_match_attr(struct compiler *c, expr_ty attr) { - if (meth->lineno != meth->end_lineno) { - // Make start location match attribute - c->u->u_lineno = c->u->u_end_lineno = meth->end_lineno; - int len = (int)PyUnicode_GET_LENGTH(meth->v.Attribute.attr); - if (len <= meth->end_col_offset) { - c->u->u_col_offset = meth->end_col_offset - len; + assert(attr->kind == Attribute_kind); + if (c->u->u_lineno != attr->end_lineno) { + c->u->u_lineno = attr->end_lineno; + int len = (int)PyUnicode_GET_LENGTH(attr->v.Attribute.attr); + if (len <= attr->end_col_offset) { + c->u->u_col_offset = attr->end_col_offset - len; } else { // GH-94694: Somebody's compiling weird ASTs. Just drop the columns: - c->u->u_col_offset = c->u->u_end_col_offset = -1; + c->u->u_col_offset = -1; + c->u->u_end_col_offset = -1; + } + // Make sure the end position still follows the start position, even for + // weird ASTs: + c->u->u_end_lineno = Py_MAX(c->u->u_lineno, c->u->u_end_lineno); + if (c->u->u_lineno == c->u->u_end_lineno) { + c->u->u_end_col_offset = Py_MAX(c->u->u_col_offset, + c->u->u_end_col_offset); } } } @@ -4842,7 +4852,7 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e) /* Alright, we can optimize the code. */ VISIT(c, expr, meth->v.Attribute.value); SET_LOC(c, meth); - update_location_to_match_attr(c, meth); + update_start_location_to_match_attr(c, meth); ADDOP_NAME(c, LOAD_METHOD, meth->v.Attribute.attr, names); VISIT_SEQ(c, expr, e->v.Call.args); @@ -4853,7 +4863,7 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e) }; } SET_LOC(c, e); - update_location_to_match_attr(c, meth); + update_start_location_to_match_attr(c, meth); ADDOP_I(c, PRECALL, argsl + kwdsl); ADDOP_I(c, CALL, argsl + kwdsl); return 1; @@ -5863,23 +5873,18 @@ compiler_visit_expr1(struct compiler *c, expr_ty e) /* The following exprs can be assignment targets. */ case Attribute_kind: VISIT(c, expr, e->v.Attribute.value); + update_start_location_to_match_attr(c, e); switch (e->v.Attribute.ctx) { case Load: { - int old_lineno = c->u->u_lineno; - c->u->u_lineno = e->end_lineno; ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names); - c->u->u_lineno = old_lineno; break; } case Store: if (forbidden_name(c, e->v.Attribute.attr, e->v.Attribute.ctx)) { return 0; } - int old_lineno = c->u->u_lineno; - c->u->u_lineno = e->end_lineno; ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names); - c->u->u_lineno = old_lineno; break; case Del: ADDOP_NAME(c, DELETE_ATTR, e->v.Attribute.attr, names); @@ -5945,10 +5950,8 @@ compiler_augassign(struct compiler *c, stmt_ty s) case Attribute_kind: VISIT(c, expr, e->v.Attribute.value); ADDOP_I(c, COPY, 1); - int old_lineno = c->u->u_lineno; - c->u->u_lineno = e->end_lineno; + update_start_location_to_match_attr(c, e); ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names); - c->u->u_lineno = old_lineno; break; case Subscript_kind: VISIT(c, expr, e->v.Subscript.value); @@ -5980,7 +5983,7 @@ compiler_augassign(struct compiler *c, stmt_ty s) switch (e->kind) { case Attribute_kind: - c->u->u_lineno = e->end_lineno; + update_start_location_to_match_attr(c, e); ADDOP_I(c, SWAP, 2); ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names); break; |
