@@ -4729,19 +4729,29 @@ is_import_originated(struct compiler *c, expr_ty e)
47294729 return flags & DEF_IMPORT ;
47304730}
47314731
4732+ // If an attribute access spans multiple lines, update the current start
4733+ // location to point to the attribute name.
47324734static void
4733- update_location_to_match_attr (struct compiler * c , expr_ty meth )
4735+ update_start_location_to_match_attr (struct compiler * c , expr_ty attr )
47344736{
4735- if (meth -> lineno != meth -> end_lineno ) {
4736- // Make start location match attribute
4737- c -> u -> u_loc .lineno = c -> u -> u_loc .end_lineno = meth -> end_lineno ;
4738- int len = (int )PyUnicode_GET_LENGTH (meth -> v .Attribute .attr );
4739- if (len <= meth -> end_col_offset ) {
4740- c -> u -> u_loc .col_offset = meth -> end_col_offset - len ;
4737+ assert (attr -> kind == Attribute_kind );
4738+ struct location * loc = & c -> u -> u_loc ;
4739+ if (loc -> lineno != attr -> end_lineno ) {
4740+ loc -> lineno = attr -> end_lineno ;
4741+ int len = (int )PyUnicode_GET_LENGTH (attr -> v .Attribute .attr );
4742+ if (len <= attr -> end_col_offset ) {
4743+ loc -> col_offset = attr -> end_col_offset - len ;
47414744 }
47424745 else {
47434746 // GH-94694: Somebody's compiling weird ASTs. Just drop the columns:
4744- c -> u -> u_loc .col_offset = c -> u -> u_loc .end_col_offset = -1 ;
4747+ loc -> col_offset = -1 ;
4748+ loc -> end_col_offset = -1 ;
4749+ }
4750+ // Make sure the end position still follows the start position, even for
4751+ // weird ASTs:
4752+ loc -> end_lineno = Py_MAX (loc -> lineno , loc -> end_lineno );
4753+ if (loc -> lineno == loc -> end_lineno ) {
4754+ loc -> end_col_offset = Py_MAX (loc -> col_offset , loc -> end_col_offset );
47454755 }
47464756 }
47474757}
@@ -4788,7 +4798,7 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e)
47884798 /* Alright, we can optimize the code. */
47894799 VISIT (c , expr , meth -> v .Attribute .value );
47904800 SET_LOC (c , meth );
4791- update_location_to_match_attr (c , meth );
4801+ update_start_location_to_match_attr (c , meth );
47924802 ADDOP_NAME (c , LOAD_METHOD , meth -> v .Attribute .attr , names );
47934803 VISIT_SEQ (c , expr , e -> v .Call .args );
47944804
@@ -4799,7 +4809,7 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e)
47994809 };
48004810 }
48014811 SET_LOC (c , e );
4802- update_location_to_match_attr (c , meth );
4812+ update_start_location_to_match_attr (c , meth );
48034813 ADDOP_I (c , CALL , argsl + kwdsl );
48044814 return 1 ;
48054815}
@@ -5811,23 +5821,18 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
58115821 /* The following exprs can be assignment targets. */
58125822 case Attribute_kind :
58135823 VISIT (c , expr , e -> v .Attribute .value );
5824+ update_start_location_to_match_attr (c , e );
58145825 switch (e -> v .Attribute .ctx ) {
58155826 case Load :
58165827 {
5817- int old_lineno = c -> u -> u_loc .lineno ;
5818- c -> u -> u_loc .lineno = e -> end_lineno ;
58195828 ADDOP_NAME (c , LOAD_ATTR , e -> v .Attribute .attr , names );
5820- c -> u -> u_loc .lineno = old_lineno ;
58215829 break ;
58225830 }
58235831 case Store :
58245832 if (forbidden_name (c , e -> v .Attribute .attr , e -> v .Attribute .ctx )) {
58255833 return 0 ;
58265834 }
5827- int old_lineno = c -> u -> u_loc .lineno ;
5828- c -> u -> u_loc .lineno = e -> end_lineno ;
58295835 ADDOP_NAME (c , STORE_ATTR , e -> v .Attribute .attr , names );
5830- c -> u -> u_loc .lineno = old_lineno ;
58315836 break ;
58325837 case Del :
58335838 ADDOP_NAME (c , DELETE_ATTR , e -> v .Attribute .attr , names );
@@ -5898,10 +5903,8 @@ compiler_augassign(struct compiler *c, stmt_ty s)
58985903 case Attribute_kind :
58995904 VISIT (c , expr , e -> v .Attribute .value );
59005905 ADDOP_I (c , COPY , 1 );
5901- int old_lineno = c -> u -> u_loc .lineno ;
5902- c -> u -> u_loc .lineno = e -> end_lineno ;
5906+ update_start_location_to_match_attr (c , e );
59035907 ADDOP_NAME (c , LOAD_ATTR , e -> v .Attribute .attr , names );
5904- c -> u -> u_loc .lineno = old_lineno ;
59055908 break ;
59065909 case Subscript_kind :
59075910 VISIT (c , expr , e -> v .Subscript .value );
@@ -5941,7 +5944,7 @@ compiler_augassign(struct compiler *c, stmt_ty s)
59415944
59425945 switch (e -> kind ) {
59435946 case Attribute_kind :
5944- c -> u -> u_loc . lineno = e -> end_lineno ;
5947+ update_start_location_to_match_attr ( c , e ) ;
59455948 ADDOP_I (c , SWAP , 2 );
59465949 ADDOP_NAME (c , STORE_ATTR , e -> v .Attribute .attr , names );
59475950 break ;
0 commit comments