@@ -4783,19 +4783,29 @@ is_import_originated(struct compiler *c, expr_ty e)
4783
4783
return flags & DEF_IMPORT ;
4784
4784
}
4785
4785
4786
+ // If an attribute access spans multiple lines, update the current start
4787
+ // location to point to the attribute name.
4786
4788
static void
4787
- update_location_to_match_attr (struct compiler * c , expr_ty meth )
4789
+ update_start_location_to_match_attr (struct compiler * c , expr_ty attr )
4788
4790
{
4789
- if ( meth -> lineno != meth -> end_lineno ) {
4790
- // Make start location match attribute
4791
- c -> u -> u_lineno = c -> u -> u_end_lineno = meth -> end_lineno ;
4792
- int len = (int )PyUnicode_GET_LENGTH (meth -> v .Attribute .attr );
4793
- if (len <= meth -> end_col_offset ) {
4794
- c -> u -> u_col_offset = meth -> end_col_offset - len ;
4791
+ assert ( attr -> kind == Attribute_kind );
4792
+ if ( c -> u -> u_lineno != attr -> end_lineno ) {
4793
+ c -> u -> u_lineno = attr -> end_lineno ;
4794
+ int len = (int )PyUnicode_GET_LENGTH (attr -> v .Attribute .attr );
4795
+ if (len <= attr -> end_col_offset ) {
4796
+ c -> u -> u_col_offset = attr -> end_col_offset - len ;
4795
4797
}
4796
4798
else {
4797
4799
// GH-94694: Somebody's compiling weird ASTs. Just drop the columns:
4798
- c -> u -> u_col_offset = c -> u -> u_end_col_offset = -1 ;
4800
+ c -> u -> u_col_offset = -1 ;
4801
+ c -> u -> u_end_col_offset = -1 ;
4802
+ }
4803
+ // Make sure the end position still follows the start position, even for
4804
+ // weird ASTs:
4805
+ c -> u -> u_end_lineno = Py_MAX (c -> u -> u_lineno , c -> u -> u_end_lineno );
4806
+ if (c -> u -> u_lineno == c -> u -> u_end_lineno ) {
4807
+ c -> u -> u_end_col_offset = Py_MAX (c -> u -> u_col_offset ,
4808
+ c -> u -> u_end_col_offset );
4799
4809
}
4800
4810
}
4801
4811
}
@@ -4842,7 +4852,7 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e)
4842
4852
/* Alright, we can optimize the code. */
4843
4853
VISIT (c , expr , meth -> v .Attribute .value );
4844
4854
SET_LOC (c , meth );
4845
- update_location_to_match_attr (c , meth );
4855
+ update_start_location_to_match_attr (c , meth );
4846
4856
ADDOP_NAME (c , LOAD_METHOD , meth -> v .Attribute .attr , names );
4847
4857
VISIT_SEQ (c , expr , e -> v .Call .args );
4848
4858
@@ -4853,7 +4863,7 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e)
4853
4863
};
4854
4864
}
4855
4865
SET_LOC (c , e );
4856
- update_location_to_match_attr (c , meth );
4866
+ update_start_location_to_match_attr (c , meth );
4857
4867
ADDOP_I (c , PRECALL , argsl + kwdsl );
4858
4868
ADDOP_I (c , CALL , argsl + kwdsl );
4859
4869
return 1 ;
@@ -5863,23 +5873,18 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
5863
5873
/* The following exprs can be assignment targets. */
5864
5874
case Attribute_kind :
5865
5875
VISIT (c , expr , e -> v .Attribute .value );
5876
+ update_start_location_to_match_attr (c , e );
5866
5877
switch (e -> v .Attribute .ctx ) {
5867
5878
case Load :
5868
5879
{
5869
- int old_lineno = c -> u -> u_lineno ;
5870
- c -> u -> u_lineno = e -> end_lineno ;
5871
5880
ADDOP_NAME (c , LOAD_ATTR , e -> v .Attribute .attr , names );
5872
- c -> u -> u_lineno = old_lineno ;
5873
5881
break ;
5874
5882
}
5875
5883
case Store :
5876
5884
if (forbidden_name (c , e -> v .Attribute .attr , e -> v .Attribute .ctx )) {
5877
5885
return 0 ;
5878
5886
}
5879
- int old_lineno = c -> u -> u_lineno ;
5880
- c -> u -> u_lineno = e -> end_lineno ;
5881
5887
ADDOP_NAME (c , STORE_ATTR , e -> v .Attribute .attr , names );
5882
- c -> u -> u_lineno = old_lineno ;
5883
5888
break ;
5884
5889
case Del :
5885
5890
ADDOP_NAME (c , DELETE_ATTR , e -> v .Attribute .attr , names );
@@ -5945,10 +5950,8 @@ compiler_augassign(struct compiler *c, stmt_ty s)
5945
5950
case Attribute_kind :
5946
5951
VISIT (c , expr , e -> v .Attribute .value );
5947
5952
ADDOP_I (c , COPY , 1 );
5948
- int old_lineno = c -> u -> u_lineno ;
5949
- c -> u -> u_lineno = e -> end_lineno ;
5953
+ update_start_location_to_match_attr (c , e );
5950
5954
ADDOP_NAME (c , LOAD_ATTR , e -> v .Attribute .attr , names );
5951
- c -> u -> u_lineno = old_lineno ;
5952
5955
break ;
5953
5956
case Subscript_kind :
5954
5957
VISIT (c , expr , e -> v .Subscript .value );
@@ -5980,7 +5983,7 @@ compiler_augassign(struct compiler *c, stmt_ty s)
5980
5983
5981
5984
switch (e -> kind ) {
5982
5985
case Attribute_kind :
5983
- c -> u -> u_lineno = e -> end_lineno ;
5986
+ update_start_location_to_match_attr ( c , e ) ;
5984
5987
ADDOP_I (c , SWAP , 2 );
5985
5988
ADDOP_NAME (c , STORE_ATTR , e -> v .Attribute .attr , names );
5986
5989
break ;
0 commit comments