diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_patmat.py b/graalpython/com.oracle.graal.python.test/src/tests/test_patmat.py index d1b6efe2a1..80219f12c0 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_patmat.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_patmat.py @@ -1,4 +1,4 @@ -# Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -262,4 +262,16 @@ def test_unbound_local_variable(self): match (1, 3): case (a, 1) | (a, 2): pass - assert a == 1 \ No newline at end of file + assert a == 1 + + def test_missing_kwarg(self): + def f(): + x = sum + match x: + case object(factor=x) if x is not None: + pass + + try: + f() + except AttributeError: + self.fail("Invalid keyword argument should not raise AttributeError") diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/MatchClassNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/MatchClassNode.java index 26e7ded5b1..adb0911187 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/MatchClassNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/MatchClassNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -139,7 +139,14 @@ Object match(VirtualFrame frame, Object subject, Object type, int nargs, @NeverD attrs = new Object[kwArgs.length]; } // Finally, the keyword subpatterns: - getKwArgs(frame, inliningTarget, subject, type, kwArgs, seen, seenLength, attrs, attrsLength, getAttr, eqStrNode, raise); + try { + getKwArgs(frame, inliningTarget, subject, type, kwArgs, seen, seenLength, attrs, attrsLength, getAttr, eqStrNode, raise); + } catch (PException pe) { + // missing keyword argument will throw AttributeError, but in pattern matching, that + // should be ignored + pe.expectAttributeError(inliningTarget, isClassProfile); + return null; + } return PFactory.createList(language, attrs); }