Skip to content

Commit 3b7072e

Browse files
mvanhornclaude
andcommitted
gh-145239: Specialize match syntax error for unary addition in pattern
Add a specialized syntax error message when unary '+' is used in match patterns. Instead of the generic "invalid syntax", users now see: "cannot use unary '+' in a literal pattern". This applies to all pattern contexts: top-level, alternatives, sequences, class patterns, and mapping patterns. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 0156133 commit 3b7072e

5 files changed

Lines changed: 342 additions & 201 deletions

File tree

Grammar/python.gram

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,7 @@ literal_pattern[pattern_ty]:
536536
| 'None' { _PyAST_MatchSingleton(Py_None, EXTRA) }
537537
| 'True' { _PyAST_MatchSingleton(Py_True, EXTRA) }
538538
| 'False' { _PyAST_MatchSingleton(Py_False, EXTRA) }
539+
| invalid_literal_pattern
539540

540541
# Literal expressions are used to restrict permitted mapping pattern keys
541542
literal_expr[expr_ty]:
@@ -1519,6 +1520,8 @@ invalid_mapping_pattern:
15191520
"double star pattern must be the last (right-most) subpattern in the mapping pattern") }
15201521
invalid_class_argument_pattern[asdl_pattern_seq*]:
15211522
| [positional_patterns ','] keyword_patterns ',' a=positional_patterns { a }
1523+
invalid_literal_pattern:
1524+
| a='+' NUMBER { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot use unary '+' in a literal pattern") }
15221525
invalid_if_stmt:
15231526
| 'if' named_expression NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
15241527
| a='if' a=named_expression ':' NEWLINE !INDENT {

Lib/test/test_patma.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3230,6 +3230,41 @@ def test_mapping_pattern_duplicate_key_edge_case3(self):
32303230
pass
32313231
""")
32323232

3233+
def test_unary_add_in_literal_pattern(self):
3234+
self.assert_syntax_error("""
3235+
match ...:
3236+
case +1:
3237+
pass
3238+
""")
3239+
3240+
def test_unary_add_in_or_pattern(self):
3241+
self.assert_syntax_error("""
3242+
match ...:
3243+
case 1 | +2 | -3:
3244+
pass
3245+
""")
3246+
3247+
def test_unary_add_in_sequence_pattern(self):
3248+
self.assert_syntax_error("""
3249+
match ...:
3250+
case [1, +2, -3]:
3251+
pass
3252+
""")
3253+
3254+
def test_unary_add_in_class_pattern(self):
3255+
self.assert_syntax_error("""
3256+
match ...:
3257+
case Foo(x=+1, y=-2):
3258+
pass
3259+
""")
3260+
3261+
def test_unary_add_in_mapping_pattern(self):
3262+
self.assert_syntax_error("""
3263+
match ...:
3264+
case {True: +1, False: -2}:
3265+
pass
3266+
""")
3267+
32333268
class TestTypeErrors(unittest.TestCase):
32343269

32353270
def test_accepts_positional_subpatterns_0(self):

Lib/test/test_syntax.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2399,6 +2399,38 @@
23992399
Traceback (most recent call last):
24002400
SyntaxError: double star pattern must be the last (right-most) subpattern in the mapping pattern
24012401
2402+
Unary '+' is not allowed in match patterns:
2403+
2404+
>>> match ...:
2405+
... case +1:
2406+
... ...
2407+
Traceback (most recent call last):
2408+
SyntaxError: cannot use unary '+' in a literal pattern
2409+
2410+
>>> match ...:
2411+
... case 1 | +2 | -3:
2412+
... ...
2413+
Traceback (most recent call last):
2414+
SyntaxError: cannot use unary '+' in a literal pattern
2415+
2416+
>>> match ...:
2417+
... case [1, +2, -3]:
2418+
... ...
2419+
Traceback (most recent call last):
2420+
SyntaxError: cannot use unary '+' in a literal pattern
2421+
2422+
>>> match ...:
2423+
... case Foo(x=+1, y=-2):
2424+
... ...
2425+
Traceback (most recent call last):
2426+
SyntaxError: cannot use unary '+' in a literal pattern
2427+
2428+
>>> match ...:
2429+
... case {True: +1, False: -2}:
2430+
... ...
2431+
Traceback (most recent call last):
2432+
SyntaxError: cannot use unary '+' in a literal pattern
2433+
24022434
Uses of the star operator which should fail:
24032435
24042436
A[:*b]
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Improved the error message when using unary ``+`` in a :keyword:`match`
2+
pattern. Instead of a generic "invalid syntax", Python now reports "cannot
3+
use unary '+' in a literal pattern".

0 commit comments

Comments
 (0)