@@ -11889,10 +11889,7 @@ mod ruff_tests {
1188911889#[cfg(test)]
1189011890mod tests {
1189111891 use super::*;
11892- use rustpython_compiler_core::{
11893- SourceFileBuilder,
11894- bytecode::{CodeUnit, OpArg},
11895- };
11892+ use rustpython_compiler_core::{SourceFileBuilder, bytecode::OpArg};
1189611893
1189711894 fn assert_scope_exit_locations(code: &CodeObject) {
1189811895 for (instr, (location, _)) in code.instructions.iter().zip(code.locations.iter()) {
@@ -22405,159 +22402,6 @@ def f(self):
2240522402 );
2240622403 }
2240722404
22408- #[test]
22409- fn test_named_except_cleanup_or_guard_tail_keeps_borrow() {
22410- let code = compile_exec(
22411- "\
22412- def f(self, nd, slices):
22413- listerr = None
22414- try:
22415- sliced = multislice(lst, slices)
22416- except Exception as e:
22417- listerr = e.__class__
22418- nderr = None
22419- try:
22420- ndsliced = nd[slices]
22421- except Exception as e:
22422- nderr = e.__class__
22423- if nderr or listerr:
22424- self.assertIs(nderr, listerr)
22425- else:
22426- self.assertEqual(ndsliced.tolist(), sliced)
22427- ",
22428- );
22429- let f = find_code(&code, "f").expect("missing f code");
22430- let instructions: Vec<_> = f
22431- .instructions
22432- .iter()
22433- .filter(|unit| !matches!(unit.op, Instruction::Cache))
22434- .collect();
22435- let assert_is_idx = instructions
22436- .iter()
22437- .position(|unit| match unit.op {
22438- Instruction::LoadAttr { namei } => {
22439- let load_attr = namei.get(OpArg::new(u32::from(u8::from(unit.arg))));
22440- f.names[usize::try_from(load_attr.name_idx()).unwrap()].as_str() == "assertIs"
22441- }
22442- _ => false,
22443- })
22444- .expect("missing assertIs LOAD_ATTR");
22445- let tail = &instructions[assert_is_idx.saturating_sub(1)..];
22446-
22447- assert!(
22448- matches!(
22449- tail.first().map(|unit| unit.op),
22450- Some(Instruction::LoadFastBorrow { .. })
22451- ),
22452- "named-except `a or b` normal tail should keep borrowed receiver, got tail={tail:?}"
22453- );
22454- assert!(
22455- tail.iter().any(|unit| {
22456- matches!(
22457- unit.op,
22458- Instruction::LoadFastBorrow { .. }
22459- | Instruction::LoadFastBorrowLoadFastBorrow { .. }
22460- )
22461- }),
22462- "named-except `a or b` normal tail should keep borrowed arguments, got tail={tail:?}"
22463- );
22464- }
22465-
22466- #[test]
22467- fn test_named_except_cleanup_slice_assign_tail_keeps_borrow() {
22468- let code = compile_exec(
22469- "\
22470- def f(self, items, lslice, rslice, ndarray, memoryview, ValueError,
22471- is_memoryview_format, fmt):
22472- nd = ndarray(items, shape=[5], format=fmt)
22473- ex = ndarray(items, shape=[5], format=fmt)
22474- mv = memoryview(ex)
22475- lsterr = None
22476- diff_structure = None
22477- lst = items[:]
22478- try:
22479- lval = lst[lslice]
22480- rval = lst[rslice]
22481- lst[lslice] = lst[rslice]
22482- diff_structure = len(lval) != len(rval)
22483- except Exception as e:
22484- lsterr = e.__class__
22485- nderr = None
22486- try:
22487- nd[lslice] = nd[rslice]
22488- except Exception as e:
22489- nderr = e.__class__
22490- if diff_structure:
22491- self.assertIs(nderr, ValueError)
22492- else:
22493- self.assertEqual(nd.tolist(), lst)
22494- self.assertIs(nderr, lsterr)
22495- if not is_memoryview_format(fmt):
22496- return
22497- mverr = None
22498- try:
22499- mv[lslice] = mv[rslice]
22500- except Exception as e:
22501- mverr = e.__class__
22502- if diff_structure:
22503- self.assertIs(mverr, ValueError)
22504- else:
22505- self.assertEqual(mv.tolist(), lst)
22506- self.assertEqual(mv, nd)
22507- self.assertIs(mverr, lsterr)
22508- ",
22509- );
22510- let f = find_code(&code, "f").expect("missing f code");
22511- let instructions: Vec<_> = f
22512- .instructions
22513- .iter()
22514- .filter(|unit| !matches!(unit.op, Instruction::Cache))
22515- .collect();
22516- let handler_start = instructions
22517- .iter()
22518- .position(|unit| matches!(unit.op, Instruction::PushExcInfo))
22519- .unwrap_or(instructions.len());
22520- let normal_path = &instructions[..handler_start];
22521- let load_fast_name = |unit: &CodeUnit| match unit.op {
22522- Instruction::LoadFast { var_num } | Instruction::LoadFastBorrow { var_num } => {
22523- let idx = usize::from(var_num.get(OpArg::new(u32::from(u8::from(unit.arg)))));
22524- Some(f.varnames[idx].as_str())
22525- }
22526- _ => None,
22527- };
22528-
22529- assert!(
22530- normal_path.windows(3).any(|window| {
22531- matches!(window[0].op, Instruction::LoadFastBorrow { .. })
22532- && load_fast_name(window[0]) == Some("diff_structure")
22533- && matches!(window[1].op, Instruction::ToBool)
22534- && matches!(window[2].op, Instruction::PopJumpIfFalse { .. })
22535- }),
22536- "expected named-except resume guard to keep borrowed diff_structure load, got normal_path={normal_path:?}"
22537- );
22538- assert!(
22539- normal_path.windows(4).any(|window| {
22540- matches!(
22541- window[0].op,
22542- Instruction::LoadFastBorrowLoadFastBorrow { .. }
22543- ) && matches!(window[1].op, Instruction::BinaryOp { .. })
22544- && matches!(
22545- window[2].op,
22546- Instruction::LoadFastBorrowLoadFastBorrow { .. }
22547- )
22548- && matches!(window[3].op, Instruction::StoreSubscr)
22549- }),
22550- "expected slice assignment normal path to keep borrowed local loads, got normal_path={normal_path:?}"
22551- );
22552- assert!(
22553- normal_path.windows(2).any(|window| {
22554- matches!(window[0].op, Instruction::LoadFastBorrow { .. })
22555- && matches!(window[1].op, Instruction::LoadAttr { .. })
22556- }),
22557- "expected named-except slice-assign tail method calls to keep borrowed receivers, got normal_path={normal_path:?}"
22558- );
22559- }
22560-
2256122405 #[test]
2256222406 fn test_with_suppress_named_except_resume_tail_uses_strong_loads() {
2256322407 let code = compile_exec(
0 commit comments