How to Resolve Python "SyntaxError: invalid syntax" with match/case Statements
Python 3.10 introduced a powerful feature called Structural Pattern Matching, implemented using the match
and case
keywords. If you attempt to use this syntax but encounter a SyntaxError: invalid syntax
, it typically means you're either running an incompatible (older) version of Python or there's a syntax mistake in or around your match
/case
block.
This guide explains the requirements for using match
/case
and how to diagnose and fix common syntax errors.
Understanding match
/case
(Structural Pattern Matching)
Introduced in Python 3.10, the match
/case
statement provides a way to compare a value (the subject
) against several possible patterns (case
) and execute code based on the first successful match. It's similar to switch
statements in other languages but much more powerful due to pattern matching capabilities.
Basic Syntax:
match subject_variable:
case pattern_1:
# Action for pattern 1
print("Matched pattern 1")
case pattern_2:
# Action for pattern 2
print("Matched pattern 2")
case _: # Wildcard (optional default)
# Action if no other pattern matches
print("No specific match")
Cause 1: Using Python Version Older Than 3.10
This is the most common reason for the SyntaxError
when first trying match
/case
. The syntax simply did not exist before Python 3.10.
# Error Scenario (when run with Python 3.9 or older)
status_code = 404
def get_message(status):
# The line below causes the error in < Python 3.10
match status: # ⛔️ SyntaxError: invalid syntax
case 404:
return "Not Found"
case 200:
return "OK"
case _:
return "Other"
try:
# This call won't even be reached if the syntax error occurs during parsing
message = get_message(status_code)
print(message)
except SyntaxError as e:
print(f"Caught SyntaxError (likely due to Python version < 3.10): {e}")
except Exception as e:
print(f"Caught other error: {e}") # Catch other potential errors too
The Python interpreter sees the match
keyword and, if it's an older version, doesn't recognize it as valid syntax.
Solution 1: Check and Update Your Python Version
Verify the Python version you are using to run the script.
- Open your terminal or command prompt.
- Run:
python --version
# Or, depending on your system setup:
python3 --version
py --version # Windows - If the output version is less than
3.10.0
, you need to either:- Upgrade Python: Download and install the latest stable Python 3 version from python.org. Ensure your system's PATH and your project/IDE environment point to the new version.
- Use an environment with Python 3.10+: If you use tools like
pyenv
orconda
, switch to or create an environment using Python 3.10 or newer. - Rewrite the code: If upgrading is not possible, use alternative control flow structures (see next section).
Alternative for Older Python Versions (< 3.10)
If you cannot use Python 3.10+, you must rewrite the logic using traditional if
/elif
/else
statements or dictionary lookups.
- Using
if
/elif
/else
:def get_message_legacy(status):
if status == 404:
return "Not Found"
elif status == 200:
return "OK"
elif status == 500:
return "Server Error"
else: # Default case
return "Other"
print(f"Legacy check (404): {get_message_legacy(404)}") # Output: Legacy check (404): Not Found
print(f"Legacy check (999): {get_message_legacy(999)}") # Output: Legacy check (999): Other - Using Dictionary
get()
: Suitable when matching specific literal values.def get_message_dict(status):
status_map = {
404: "Not Found",
200: "OK",
500: "Server Error"
}
# Return the value from the dict, or the default message if key not found
return status_map.get(status, "Other") # "Other" is the default
print(f"Dict check (200): {get_message_dict(200)}") # Output: Dict check (200): OK
print(f"Dict check (401): {get_message_dict(401)}") # Output: Dict check (401): Other
Cause 2: Syntax Errors Within the match
/case
Block
Even if using Python 3.10+, syntax errors within the match
or case
statements themselves will cause the SyntaxError
.
Missing Colons (:
)
Both the match subject
line and every case pattern
line must end with a colon (:
).
# Error Scenario: Missing colon after 'match' or 'case'
value = "A"
try:
match value # ⛔️ SyntaxError: invalid syntax (expected ':')
case "A":
print("It's A")
except SyntaxError as e:
print(f"Error (missing colon): {e}")
try:
match value:
case "A" # ⛔️ SyntaxError: invalid syntax (expected ':')
print("It's A")
except SyntaxError as e:
print(f"Error (missing colon): {e}")
Incorrect Indentation
The action block following each case pattern:
line must be indented, and all lines within that block must have consistent indentation.
# Error Scenario: Incorrect indentation
value = "B"
try:
match value:
case "A":
print("It's A")
case "B":
print("It's B") # ⛔️ IndentationError: expected an indented block
except IndentationError as e: # Or sometimes SyntaxError
print(f"Error (bad indent): {e}")
Invalid Case Patterns
While powerful, case
patterns have rules. Using invalid expressions as patterns (e.g., function calls directly in the pattern) can cause errors. For basic use, focus on literals (numbers, strings), variable names (captures), wildcards (_
), and simple structures.
Solution 2: Correct the match
/case
Syntax
Carefully review your match
/case
block against the standard syntax:
- Ensure
match subject:
ends with a colon (:
). - Ensure every
case pattern:
line ends with a colon (:
). - Ensure the code block under each
case
is correctly and consistently indented. - Ensure your
case
patterns are valid (refer to Python documentation for complex patterns if needed).
# Correct Syntax Example
def process_value(value):
match value: # Colon after match
case 1: # Colon after case
print("Value is one") # Indented action
case "hello": # Colon after case
print("Value is hello") # Indented action
print("Another action") # Consistently indented
case _: # Colon after wildcard case
print("Other value") # Indented action
process_value(1)
process_value("hello")
process_value(99.9)
Output:
Value is one
Value is hello
Another action
Other value
Cause 3: Syntax Error Before the match
Statement
Sometimes, a SyntaxError
reported on the match
line is actually caused by an error on a preceding line, such as an unclosed parenthesis, bracket, or quote. The parser gets confused and reports the error at the first keyword (match
) it doesn't expect.
# Error Scenario: Unclosed parenthesis on the line before
my_list = [1, 2, 3 # ⛔️ Missing closing ']'
# Python might report the error on the 'match' line below
# because it didn't expect 'match' after the incomplete list definition.
# match some_variable:
# case ...
try:
eval("my_list = [1, 2, 3 \nmatch 5:\n case 5: pass") # Simulate multi-line parsing
except SyntaxError as e:
print(f"Error likely caused by preceding line: {e}") # Error might mention EOF or unexpected keyword
Solution 3: Check Preceding Code
If the syntax within your match
/case
block looks correct, carefully inspect the lines immediately before the match
statement for:
- Unclosed parentheses
(
, square brackets[
, or curly braces{
. - Unclosed quotes
'
or"
. - Other syntax errors.
Debugging Tip: Temporarily comment out the entire match
/case
block. If the SyntaxError
disappears or moves to the line before where the match
block started, the issue is in the preceding code.
Debugging Checklist
When facing SyntaxError: invalid syntax
near match
/case
:
- Python Version: Are you running Python 3.10 or newer (
python --version
)? - Colon after
match
: Does thematch subject:
line end with a colon? - Colon after
case
: Does everycase pattern:
line end with a colon? - Indentation: Is the code block under each
case
indented correctly and consistently? - Pattern Validity: Are your
case
patterns valid (e.g., literals, variables,_
)? - Preceding Code: Is there a syntax error (like unclosed brackets/quotes) on the lines before the
match
statement?
Conclusion
The SyntaxError: invalid syntax
when using match
/case
most often stems from:
- Using a Python version older than 3.10. Solution: Upgrade Python or use
if/elif/else
/dictionaries. - Incorrect syntax within the
match
/case
block itself (missing colons:
, bad indentation). Solution: Correct the syntax according to thematch subject: case pattern: action
structure. - A syntax error on a line preceding the
match
statement. Solution: Carefully review the code above thematch
block.
By verifying your Python version and carefully checking the syntax around and within your match
/case
statements, you can effectively resolve this error.