From b807bc7fc4891613fbd0ab41b74b9be21b1ec063 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Tue, 26 Aug 2025 15:12:35 +0900 Subject: [PATCH] Fix patma guard --- Lib/test/test_patma.py | 7 ------- compiler/codegen/src/compile.rs | 4 ++-- vm/src/frame.rs | 16 ++++++++++------ 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/Lib/test/test_patma.py b/Lib/test/test_patma.py index aa07c7ed9..5b2755f83 100644 --- a/Lib/test/test_patma.py +++ b/Lib/test/test_patma.py @@ -586,7 +586,6 @@ class TestPatma(unittest.TestCase): self.assertEqual(y, 1) self.assertEqual(z, 0) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_patma_052(self): x = [1, 0] match x: @@ -1904,7 +1903,6 @@ class TestPatma(unittest.TestCase): self.assertEqual(whereis([Point(0, 0), Point(0, 0), Point(0, 0)]), "Something else") self.assertEqual(whereis([Point(0, 1), Point(0, 1), Point(0, 1)]), "Something else") - @unittest.expectedFailure # TODO: RUSTPYTHON def test_patma_183(self): def whereis(point): match point: @@ -2695,7 +2693,6 @@ class TestPatma(unittest.TestCase): setattr(c, "__attr", "spam") # setattr is needed because we're in a class scope self.assertEqual(Outer().f(c), "spam") - @unittest.expectedFailure # TODO: RUSTPYTHON def test_patma_250(self): def f(x): match x: @@ -2707,7 +2704,6 @@ class TestPatma(unittest.TestCase): self.assertIs(f({"foo": 1}), True) self.assertIs(f({"foo": -1}), False) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_patma_251(self): def f(v, x): match v: @@ -2726,7 +2722,6 @@ class TestPatma(unittest.TestCase): self.assertIs(f(-1, X(-1)), False) self.assertIs(f(1, X(-1)), None) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_patma_252(self): # Side effects must be possible in guards: effects = [] @@ -2764,7 +2759,6 @@ class TestPatma(unittest.TestCase): self.assertEqual(f(1), 1) self.assertEqual(f({"x": 1}), 1) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_patma_255(self): x = [] match x: @@ -3259,7 +3253,6 @@ class TestTypeErrors(unittest.TestCase): self.assertIs(y, None) self.assertIs(z, None) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_accepts_positional_subpatterns_1(self): x = range(10) y = None diff --git a/compiler/codegen/src/compile.rs b/compiler/codegen/src/compile.rs index 8bcb133cc..41a4b6e82 100644 --- a/compiler/codegen/src/compile.rs +++ b/compiler/codegen/src/compile.rs @@ -4011,10 +4011,10 @@ impl Compiler { self.ensure_fail_pop(pattern_context, 0)?; // Compile the guard expression self.compile_expression(guard)?; - // If guard is false, jump to fail_pop[0] + emit!(self, Instruction::ToBool); emit!( self, - Instruction::JumpIfFalseOrPop { + Instruction::PopJumpIfFalse { target: pattern_context.fail_pop[0] } ); diff --git a/vm/src/frame.rs b/vm/src/frame.rs index 45bc4f592..ec03eef22 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -1440,14 +1440,18 @@ impl ExecutingFrame<'_> { extracted.push(subject.clone()); } else if nargs_val > 1 { // Too many positional arguments for MATCH_SELF - self.push_value(vm.ctx.none()); - return Ok(None); + return Err(vm.new_type_error( + "class pattern accepts at most 1 positional sub-pattern for MATCH_SELF types" + .to_string(), + )); } } else { // No __match_args__ and not a MATCH_SELF type if nargs_val > 0 { - self.push_value(vm.ctx.none()); - return Ok(None); + return Err(vm.new_type_error( + "class pattern defines no positional sub-patterns (__match_args__ missing)" + .to_string(), + )); } } } @@ -1458,11 +1462,11 @@ impl ExecutingFrame<'_> { let name_str = name.downcast_ref::().unwrap(); match subject.get_attr(name_str, vm) { Ok(value) => extracted.push(value), - Err(_) => { - // Attribute doesn't exist + Err(e) if e.fast_isinstance(vm.ctx.exceptions.attribute_error) => { self.push_value(vm.ctx.none()); return Ok(None); } + Err(e) => return Err(e), } }