@@ -4729,19 +4729,29 @@ is_import_originated(struct compiler *c, expr_ty e)
4729
4729
return flags & DEF_IMPORT ;
4730
4730
}
4731
4731
4732
+ // If an attribute access spans multiple lines, update the current start
4733
+ // location to point to the attribute name.
4732
4734
static 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 )
4734
4736
{
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 ;
4741
4744
}
4742
4745
else {
4743
4746
// 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 );
4745
4755
}
4746
4756
}
4747
4757
}
@@ -4788,7 +4798,7 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e)
4788
4798
/* Alright, we can optimize the code. */
4789
4799
VISIT (c , expr , meth -> v .Attribute .value );
4790
4800
SET_LOC (c , meth );
4791
- update_location_to_match_attr (c , meth );
4801
+ update_start_location_to_match_attr (c , meth );
4792
4802
ADDOP_NAME (c , LOAD_METHOD , meth -> v .Attribute .attr , names );
4793
4803
VISIT_SEQ (c , expr , e -> v .Call .args );
4794
4804
@@ -4799,7 +4809,7 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e)
4799
4809
};
4800
4810
}
4801
4811
SET_LOC (c , e );
4802
- update_location_to_match_attr (c , meth );
4812
+ update_start_location_to_match_attr (c , meth );
4803
4813
ADDOP_I (c , CALL , argsl + kwdsl );
4804
4814
return 1 ;
4805
4815
}
@@ -5811,23 +5821,18 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
5811
5821
/* The following exprs can be assignment targets. */
5812
5822
case Attribute_kind :
5813
5823
VISIT (c , expr , e -> v .Attribute .value );
5824
+ update_start_location_to_match_attr (c , e );
5814
5825
switch (e -> v .Attribute .ctx ) {
5815
5826
case Load :
5816
5827
{
5817
- int old_lineno = c -> u -> u_loc .lineno ;
5818
- c -> u -> u_loc .lineno = e -> end_lineno ;
5819
5828
ADDOP_NAME (c , LOAD_ATTR , e -> v .Attribute .attr , names );
5820
- c -> u -> u_loc .lineno = old_lineno ;
5821
5829
break ;
5822
5830
}
5823
5831
case Store :
5824
5832
if (forbidden_name (c , e -> v .Attribute .attr , e -> v .Attribute .ctx )) {
5825
5833
return 0 ;
5826
5834
}
5827
- int old_lineno = c -> u -> u_loc .lineno ;
5828
- c -> u -> u_loc .lineno = e -> end_lineno ;
5829
5835
ADDOP_NAME (c , STORE_ATTR , e -> v .Attribute .attr , names );
5830
- c -> u -> u_loc .lineno = old_lineno ;
5831
5836
break ;
5832
5837
case Del :
5833
5838
ADDOP_NAME (c , DELETE_ATTR , e -> v .Attribute .attr , names );
@@ -5898,10 +5903,8 @@ compiler_augassign(struct compiler *c, stmt_ty s)
5898
5903
case Attribute_kind :
5899
5904
VISIT (c , expr , e -> v .Attribute .value );
5900
5905
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 );
5903
5907
ADDOP_NAME (c , LOAD_ATTR , e -> v .Attribute .attr , names );
5904
- c -> u -> u_loc .lineno = old_lineno ;
5905
5908
break ;
5906
5909
case Subscript_kind :
5907
5910
VISIT (c , expr , e -> v .Subscript .value );
@@ -5941,7 +5944,7 @@ compiler_augassign(struct compiler *c, stmt_ty s)
5941
5944
5942
5945
switch (e -> kind ) {
5943
5946
case Attribute_kind :
5944
- c -> u -> u_loc . <
564B
span class="pl-c1 x">lineno = e -> end_lineno ;
5947
+ update_start_location_to_match_attr ( c , e ) ;
5945
5948
ADDOP_I (c , SWAP , 2 );
5946
5949
ADDOP_NAME (c , STORE_ATTR , e -> v .Attribute .attr , names );
5947
5950
break ;
0 commit comments