(&self, value: PySetterValue, vm: &VirtualMachine)
| 484 | |
| 485 | #[pygetset(setter)] |
| 486 | fn set_f_lineno(&self, value: PySetterValue, vm: &VirtualMachine) -> PyResult<()> { |
| 487 | let l_new_lineno = match value { |
| 488 | PySetterValue::Assign(val) => { |
| 489 | let line_ref: PyIntRef = val |
| 490 | .downcast() |
| 491 | .map_err(|_| vm.new_value_error("lineno must be an integer"))?; |
| 492 | line_ref |
| 493 | .try_to_primitive::<i32>(vm) |
| 494 | .map_err(|_| vm.new_value_error("lineno must be an integer"))? |
| 495 | } |
| 496 | PySetterValue::Delete => { |
| 497 | return Err(vm.new_type_error("can't delete f_lineno attribute")); |
| 498 | } |
| 499 | }; |
| 500 | |
| 501 | let first_line = self |
| 502 | .code |
| 503 | .first_line_number |
| 504 | .map(|n| n.get() as i32) |
| 505 | .unwrap_or(1); |
| 506 | |
| 507 | if l_new_lineno < first_line { |
| 508 | return Err(vm.new_value_error(format!( |
| 509 | "line {l_new_lineno} comes before the current code block" |
| 510 | ))); |
| 511 | } |
| 512 | |
| 513 | let py_code: &PyCode = &self.code; |
| 514 | let code = &py_code.code; |
| 515 | let lines = mark_lines(code); |
| 516 | |
| 517 | // Find the first line >= target that has actual code |
| 518 | let new_lineno = first_line_not_before(&lines, l_new_lineno); |
| 519 | if new_lineno < 0 { |
| 520 | return Err(vm.new_value_error(format!( |
| 521 | "line {l_new_lineno} comes after the current code block" |
| 522 | ))); |
| 523 | } |
| 524 | |
| 525 | let stacks = mark_stacks(code); |
| 526 | let len = self.code.instructions.len(); |
| 527 | |
| 528 | // lasti points past the current instruction (already incremented). |
| 529 | // stacks[lasti - 1] gives the stack state before executing the |
| 530 | // instruction that triggered this trace event, which is the current |
| 531 | // evaluation stack. |
| 532 | let current_lasti = self.lasti() as usize; |
| 533 | let start_idx = current_lasti.saturating_sub(1); |
| 534 | let start_stack = if start_idx < stacks.len() { |
| 535 | stacks[start_idx] |
| 536 | } else { |
| 537 | OVERFLOWED |
| 538 | }; |
| 539 | let mut best_stack = OVERFLOWED; |
| 540 | let mut best_addr: i32 = -1; |
| 541 | let mut err: i32 = -1; |
| 542 | let mut msg = "cannot find bytecode for specified line"; |
| 543 |
nothing calls this directly
no test coverage detected