@@ -160,6 +160,20 @@ fn text_range_to_source_range(source_file: &SourceFile, text_range: TextRange) -
160160 }
161161}
162162
163+ fn get_opt_int_field (
164+ vm : & VirtualMachine ,
165+ obj : & PyObject ,
166+ field : & ' static str ,
167+ ) -> PyResult < Option < PyRefExact < PyInt > > > {
168+ match get_node_field_opt ( vm, obj, field) ? {
169+ Some ( val) => val
170+ . downcast_exact ( vm)
171+ . map ( Some )
172+ . map_err ( |_| vm. new_type_error ( format ! ( r#"field "{field}" must have integer type"# ) ) ) ,
173+ None => Ok ( None ) ,
174+ }
175+ }
176+
163177fn range_from_object (
164178 vm : & VirtualMachine ,
165179 source_file : & SourceFile ,
@@ -168,17 +182,35 @@ fn range_from_object(
168182) -> PyResult < TextRange > {
169183 let start_row = get_int_field ( vm, & object, "lineno" , name) ?;
170184 let start_column = get_int_field ( vm, & object, "col_offset" , name) ?;
171- let end_row = get_int_field ( vm, & object, "end_lineno" , name) ?;
172- let end_column = get_int_field ( vm, & object, "end_col_offset" , name) ?;
185+ // end_lineno and end_col_offset are optional, default to start values
186+ let end_row =
187+ get_opt_int_field ( vm, & object, "end_lineno" ) ?. unwrap_or_else ( || start_row. clone ( ) ) ;
188+ let end_column =
189+ get_opt_int_field ( vm, & object, "end_col_offset" ) ?. unwrap_or_else ( || start_column. clone ( ) ) ;
190+
191+ // lineno=0 or negative values as a special case (no location info).
192+ // Use default values (line 1, col 0) when lineno <= 0.
193+ let start_row_val: i32 = start_row. try_to_primitive ( vm) ?;
194+ let end_row_val: i32 = end_row. try_to_primitive ( vm) ?;
195+ let start_col_val: i32 = start_column. try_to_primitive ( vm) ?;
196+ let end_col_val: i32 = end_column. try_to_primitive ( vm) ?;
173197
174198 let location = PySourceRange {
175199 start : PySourceLocation {
176- row : Row ( OneIndexed :: new ( start_row. try_to_primitive ( vm) ?) . unwrap ( ) ) ,
177- column : Column ( TextSize :: new ( start_column. try_to_primitive ( vm) ?) ) ,
200+ row : Row ( if start_row_val > 0 {
201+ OneIndexed :: new ( start_row_val as usize ) . unwrap_or ( OneIndexed :: MIN )
202+ } else {
203+ OneIndexed :: MIN
204+ } ) ,
205+ column : Column ( TextSize :: new ( start_col_val. max ( 0 ) as u32 ) ) ,
178206 } ,
179207 end : PySourceLocation {
180- row : Row ( OneIndexed :: new ( end_row. try_to_primitive ( vm) ?) . unwrap ( ) ) ,
181- column : Column ( TextSize :: new ( end_column. try_to_primitive ( vm) ?) ) ,
208+ row : Row ( if end_row_val > 0 {
209+ OneIndexed :: new ( end_row_val as usize ) . unwrap_or ( OneIndexed :: MIN )
210+ } else {
211+ OneIndexed :: MIN
212+ } ) ,
213+ column : Column ( TextSize :: new ( end_col_val. max ( 0 ) as u32 ) ) ,
182214 } ,
183215 } ;
184216
0 commit comments