tree-sitters/python/test/corpus/pattern_matching.txt

1573 lines
41 KiB
Plaintext

================================================================================
Matching specific values
================================================================================
match command.split():
case ["quit"]:
print("Goodbye!")
quit_game()
case ["look"]:
current_room.describe()
case ["get", obj]:
character.get(obj, current_room)
case ["go", direction]:
current_room = current_room.neighbor(direction)
# The rest of your commands go here
--------------------------------------------------------------------------------
(module
(match_statement
(call
(attribute
(identifier)
(identifier))
(argument_list))
(block
(case_clause
(case_pattern
(list_pattern
(case_pattern
(string
(string_start)
(string_content)
(string_end)))))
(block
(expression_statement
(call
(identifier)
(argument_list
(string
(string_start)
(string_content)
(string_end)))))
(expression_statement
(call
(identifier)
(argument_list)))))
(case_clause
(case_pattern
(list_pattern
(case_pattern
(string
(string_start)
(string_content)
(string_end)))))
(block
(expression_statement
(call
(attribute
(identifier)
(identifier))
(argument_list)))))
(case_clause
(case_pattern
(list_pattern
(case_pattern
(string
(string_start)
(string_content)
(string_end)))
(case_pattern
(dotted_name
(identifier)))))
(block
(expression_statement
(call
(attribute
(identifier)
(identifier))
(argument_list
(identifier)
(identifier))))))
(case_clause
(case_pattern
(list_pattern
(case_pattern
(string
(string_start)
(string_content)
(string_end)))
(case_pattern
(dotted_name
(identifier)))))
(block
(expression_statement
(assignment
(identifier)
(call
(attribute
(identifier)
(identifier))
(argument_list
(identifier)))))))
(comment))))
================================================================================
Matching multiple values
================================================================================
match command.split():
case ["drop", *objects]:
for obj in objects:
character.drop(obj, current_room)
--------------------------------------------------------------------------------
(module
(match_statement
(call
(attribute
(identifier)
(identifier))
(argument_list))
(block
(case_clause
(case_pattern
(list_pattern
(case_pattern
(string
(string_start)
(string_content)
(string_end)))
(case_pattern
(splat_pattern
(identifier)))))
(block
(for_statement
(identifier)
(identifier)
(block
(expression_statement
(call
(attribute
(identifier)
(identifier))
(argument_list
(identifier)
(identifier)))))))))))
================================================================================
Adding a wild card
================================================================================
match command.split():
# ^ conditional
case ["quit"]: ... # Code omitted for brevity
case ["go", direction]: pass
case ["drop", *objects]: pass
case _:
print(f"Sorry, I couldn't understand {command!r}")
--------------------------------------------------------------------------------
(module
(match_statement
(call
(attribute
(identifier)
(identifier))
(argument_list))
(block
(comment)
(case_clause
(case_pattern
(list_pattern
(case_pattern
(string
(string_start)
(string_content)
(string_end)))))
(block
(expression_statement
(ellipsis))
(comment)))
(case_clause
(case_pattern
(list_pattern
(case_pattern
(string
(string_start)
(string_content)
(string_end)))
(case_pattern
(dotted_name
(identifier)))))
(block
(pass_statement)))
(case_clause
(case_pattern
(list_pattern
(case_pattern
(string
(string_start)
(string_content)
(string_end)))
(case_pattern
(splat_pattern
(identifier)))))
(block
(pass_statement)))
(case_clause
(case_pattern)
(block
(expression_statement
(call
(identifier)
(argument_list
(string
(string_start)
(string_content)
(interpolation
(identifier)
(type_conversion))
(string_end))))))))))
================================================================================
Or patterns
================================================================================
match command.split():
case ["north"] | ["go", "north"]:
current_room = current_room.neighbor("north")
case ["get", obj] | ["pick", "up", obj] | ["pick", obj, "up"]:
pass
--------------------------------------------------------------------------------
(module
(match_statement
(call
(attribute
(identifier)
(identifier))
(argument_list))
(block
(case_clause
(case_pattern
(union_pattern
(list_pattern
(case_pattern
(string
(string_start)
(string_content)
(string_end))))
(list_pattern
(case_pattern
(string
(string_start)
(string_content)
(string_end)))
(case_pattern
(string
(string_start)
(string_content)
(string_end))))))
(block
(expression_statement
(assignment
(identifier)
(call
(attribute
(identifier)
(identifier))
(argument_list
(string
(string_start)
(string_content)
(string_end))))))))
(case_clause
(case_pattern
(union_pattern
(list_pattern
(case_pattern
(string
(string_start)
(string_content)
(string_end)))
(case_pattern
(dotted_name
(identifier))))
(list_pattern
(case_pattern
(string
(string_start)
(string_content)
(string_end)))
(case_pattern
(string
(string_start)
(string_content)
(string_end)))
(case_pattern
(dotted_name
(identifier))))
(list_pattern
(case_pattern
(string
(string_start)
(string_content)
(string_end)))
(case_pattern
(dotted_name
(identifier)))
(case_pattern
(string
(string_start)
(string_content)
(string_end))))))
(block
(pass_statement))))))
================================================================================
As patterns
================================================================================
match command.split():
case ["go", ("north" | "south" | "east" | "west") as direction]:
current_room = current_room.neighbor(direction)
--------------------------------------------------------------------------------
(module
(match_statement
(call
(attribute
(identifier)
(identifier))
(argument_list))
(block
(case_clause
(case_pattern
(list_pattern
(case_pattern
(string
(string_start)
(string_content)
(string_end)))
(case_pattern
(as_pattern
(case_pattern
(tuple_pattern
(case_pattern
(union_pattern
(string
(string_start)
(string_content)
(string_end))
(string
(string_start)
(string_content)
(string_end))
(string
(string_start)
(string_content)
(string_end))
(string
(string_start)
(string_content)
(string_end))))))
(identifier)))))
(block
(expression_statement
(assignment
(identifier)
(call
(attribute
(identifier)
(identifier))
(argument_list
(identifier))))))))))
================================================================================
Actually not match
================================================================================
match = 2
match, a = 2, 3
match: int = secret
x, match = 2, "hey, what's up?"
*match, last = [1, 2, 3]
def foo(**match): pass
--------------------------------------------------------------------------------
(module
(expression_statement
(assignment
(identifier)
(integer)))
(expression_statement
(assignment
(pattern_list
(identifier)
(identifier))
(expression_list
(integer)
(integer))))
(expression_statement
(assignment
(identifier)
(type
(identifier))
(identifier)))
(expression_statement
(assignment
(pattern_list
(identifier)
(identifier))
(expression_list
(integer)
(string
(string_start)
(string_content)
(string_end)))))
(expression_statement
(assignment
(pattern_list
(list_splat_pattern
(identifier))
(identifier))
(list
(integer)
(integer)
(integer))))
(function_definition
(identifier)
(parameters
(dictionary_splat_pattern
(identifier)))
(block
(pass_statement))))
================================================================================
Match is match but not pattern matching
================================================================================
a = [match]
match = [match]
--------------------------------------------------------------------------------
(module
(expression_statement
(assignment
(identifier)
(list
(identifier))))
(expression_statement
(assignment
(identifier)
(list
(identifier)))))
================================================================================
Match kwargs
================================================================================
field = call(match=r".*\.txt$")
--------------------------------------------------------------------------------
(module
(expression_statement
(assignment
(identifier)
(call
(identifier)
(argument_list
(keyword_argument
(identifier)
(string
(string_start)
(string_content)
(string_end))))))))
================================================================================
Match kwargs 2
================================================================================
field = match(match=match, match)
--------------------------------------------------------------------------------
(module
(expression_statement
(assignment
(identifier)
(call
(identifier)
(argument_list
(keyword_argument
(identifier)
(identifier))
(identifier))))))
================================================================================
Case used as identifier
================================================================================
a = [case]
case = [case]
just_in_case = call_me(case=True)
--------------------------------------------------------------------------------
(module
(expression_statement
(assignment
(identifier)
(list
(identifier))))
(expression_statement
(assignment
(identifier)
(list
(identifier))))
(expression_statement
(assignment
(identifier)
(call
(identifier)
(argument_list
(keyword_argument
(identifier)
(true)))))))
================================================================================
If guards
================================================================================
match 0:
case 0 if False:
x = False
case 0 if True:
x = True
--------------------------------------------------------------------------------
(module
(match_statement
(integer)
(block
(case_clause
(case_pattern
(integer))
(if_clause
(false))
(block
(expression_statement
(assignment
(identifier)
(false)))))
(case_clause
(case_pattern
(integer))
(if_clause
(true))
(block
(expression_statement
(assignment
(identifier)
(true))))))))
================================================================================
Literals
================================================================================
match xxx:
case 3 | -3:
pass
case "something":
pass
case "something" "else":
pass
case 1.0 | -1.0:
pass
case True | False:
pass
case None:
pass
--------------------------------------------------------------------------------
(module
(match_statement
(identifier)
(block
(case_clause
(case_pattern
(union_pattern
(integer)
(integer)))
(block
(pass_statement)))
(case_clause
(case_pattern
(string
(string_start)
(string_content)
(string_end)))
(block
(pass_statement)))
(case_clause
(case_pattern
(concatenated_string
(string
(string_start)
(string_content)
(string_end))
(string
(string_start)
(string_content)
(string_end))))
(block
(pass_statement)))
(case_clause
(case_pattern
(union_pattern
(float)
(float)))
(block
(pass_statement)))
(case_clause
(case_pattern
(union_pattern
(true)
(false)))
(block
(pass_statement)))
(case_clause
(case_pattern
(none))
(block
(pass_statement))))))
================================================================================
Comma separated cases
================================================================================
match (0, 1, 2):
case 0,1:
x = 0
case 0, *x:
x = 0
--------------------------------------------------------------------------------
(module
(match_statement
(tuple
(integer)
(integer)
(integer))
(block
(case_clause
(case_pattern
(integer))
(case_pattern
(integer))
(block
(expression_statement
(assignment
(identifier)
(integer)))))
(case_clause
(case_pattern
(integer))
(case_pattern
(splat_pattern
(identifier)))
(block
(expression_statement
(assignment
(identifier)
(integer))))))))
================================================================================
Case terminating in comma
================================================================================
match x,:
case *x,:
y = 0
--------------------------------------------------------------------------------
(module
(match_statement
(identifier)
(block
(case_clause
(case_pattern
(splat_pattern
(identifier)))
(block
(expression_statement
(assignment
(identifier)
(integer))))))))
================================================================================
Multiple match patterns
================================================================================
match ..., ...:
case a, b:
return locals()
--------------------------------------------------------------------------------
(module
(match_statement
(ellipsis)
(ellipsis)
(block
(case_clause
(case_pattern
(dotted_name
(identifier)))
(case_pattern
(dotted_name
(identifier)))
(block
(return_statement
(call
(identifier)
(argument_list))))))))
================================================================================
Match match, case case
================================================================================
match = case = 0
match match:
case case:
x = 0
--------------------------------------------------------------------------------
(module
(expression_statement
(assignment
(identifier)
(assignment
(identifier)
(integer))))
(match_statement
(identifier)
(block
(case_clause
(case_pattern
(dotted_name
(identifier)))
(block
(expression_statement
(assignment
(identifier)
(integer))))))))
================================================================================
Walrus match (Issue #150)
================================================================================
if match := re.fullmatch(r"(-)?(\d+:)?\d?\d:\d\d(\.\d*)?", time, flags=re.ASCII):
return 42
--------------------------------------------------------------------------------
(module
(if_statement
(named_expression
(identifier)
(call
(attribute
(identifier)
(identifier))
(argument_list
(string
(string_start)
(string_content)
(string_end))
(identifier)
(keyword_argument
(identifier)
(attribute
(identifier)
(identifier))))))
(block
(return_statement
(integer)))))
================================================================================
Matching objects
================================================================================
match event.get():
case Click(position=(x, y)):
handle_click_at(x, y)
case KeyPress(key_name="Q") | Quit():
game.quit()
case KeyPress(key_name="up arrow"):
game.go_north()
...
case KeyPress():
pass # Ignore other keystrokes
case other_event:
raise ValueError(f"Unrecognized event: {other_event}")
--------------------------------------------------------------------------------
(module
(match_statement
(call
(attribute
(identifier)
(identifier))
(argument_list))
(block
(case_clause
(case_pattern
(class_pattern
(dotted_name
(identifier))
(case_pattern
(keyword_pattern
(identifier)
(tuple_pattern
(case_pattern
(dotted_name
(identifier)))
(case_pattern
(dotted_name
(identifier))))))))
(block
(expression_statement
(call
(identifier)
(argument_list
(identifier)
(identifier))))))
(case_clause
(case_pattern
(union_pattern
(class_pattern
(dotted_name
(identifier))
(case_pattern
(keyword_pattern
(identifier)
(string
(string_start)
(string_content)
(string_end)))))
(class_pattern
(dotted_name
(identifier)))))
(block
(expression_statement
(call
(attribute
(identifier)
(identifier))
(argument_list)))))
(case_clause
(case_pattern
(class_pattern
(dotted_name
(identifier))
(case_pattern
(keyword_pattern
(identifier)
(string
(string_start)
(string_content)
(string_end))))))
(block
(expression_statement
(call
(attribute
(identifier)
(identifier))
(argument_list)))
(expression_statement
(ellipsis))))
(case_clause
(case_pattern
(class_pattern
(dotted_name
(identifier))))
(block
(pass_statement)
(comment)))
(case_clause
(case_pattern
(dotted_name
(identifier)))
(block
(raise_statement
(call
(identifier)
(argument_list
(string
(string_start)
(string_content)
(interpolation
(identifier))
(string_end))))))))))
================================================================================
Positional arguments
================================================================================
match event.get():
case Click((x, y)):
handle_click_at(x, y)
--------------------------------------------------------------------------------
(module
(match_statement
(call
(attribute
(identifier)
(identifier))
(argument_list))
(block
(case_clause
(case_pattern
(class_pattern
(dotted_name
(identifier))
(case_pattern
(tuple_pattern
(case_pattern
(dotted_name
(identifier)))
(case_pattern
(dotted_name
(identifier)))))))
(block
(expression_statement
(call
(identifier)
(argument_list
(identifier)
(identifier)))))))))
================================================================================
Constants and enums
================================================================================
match event.get():
case Click((x, y), button=Button.LEFT): # This is a left click
handle_click_at(x, y)
case Click():
pass # ignore other clicks
--------------------------------------------------------------------------------
(module
(match_statement
(call
(attribute
(identifier)
(identifier))
(argument_list))
(block
(case_clause
(case_pattern
(class_pattern
(dotted_name
(identifier))
(case_pattern
(tuple_pattern
(case_pattern
(dotted_name
(identifier)))
(case_pattern
(dotted_name
(identifier)))))
(case_pattern
(keyword_pattern
(identifier)
(dotted_name
(identifier)
(identifier))))))
(comment)
(block
(expression_statement
(call
(identifier)
(argument_list
(identifier)
(identifier))))))
(case_clause
(case_pattern
(class_pattern
(dotted_name
(identifier))))
(block
(pass_statement)
(comment))))))
================================================================================
Dict mappings
================================================================================
for action in actions:
match action:
case {"text": message, "color": c}:
ui.set_text_color(c)
ui.display(message)
case {"sleep": duration}:
ui.wait(duration)
case {"sound": url, "format": "ogg"}:
ui.play(url)
case {a.b: c}:
action()
case {"sound": _, "format": _}:
warning("Unsupported audio format")
--------------------------------------------------------------------------------
(module
(for_statement
(identifier)
(identifier)
(block
(match_statement
(identifier)
(block
(case_clause
(case_pattern
(dict_pattern
(string
(string_start)
(string_content)
(string_end))
(case_pattern
(dotted_name
(identifier)))
(string
(string_start)
(string_content)
(string_end))
(case_pattern
(dotted_name
(identifier)))))
(block
(expression_statement
(call
(attribute
(identifier)
(identifier))
(argument_list
(identifier))))
(expression_statement
(call
(attribute
(identifier)
(identifier))
(argument_list
(identifier))))))
(case_clause
(case_pattern
(dict_pattern
(string
(string_start)
(string_content)
(string_end))
(case_pattern
(dotted_name
(identifier)))))
(block
(expression_statement
(call
(attribute
(identifier)
(identifier))
(argument_list
(identifier))))))
(case_clause
(case_pattern
(dict_pattern
(string
(string_start)
(string_content)
(string_end))
(case_pattern
(dotted_name
(identifier)))
(string
(string_start)
(string_content)
(string_end))
(case_pattern
(string
(string_start)
(string_content)
(string_end)))))
(block
(expression_statement
(call
(attribute
(identifier)
(identifier))
(argument_list
(identifier))))))
(case_clause
(case_pattern
(dict_pattern
(dotted_name
(identifier)
(identifier))
(case_pattern
(dotted_name
(identifier)))))
(block
(expression_statement
(call
(identifier)
(argument_list)))))
(case_clause
(case_pattern
(dict_pattern
(string
(string_start)
(string_content)
(string_end))
(case_pattern)
(string
(string_start)
(string_content)
(string_end))
(case_pattern)))
(block
(expression_statement
(call
(identifier)
(argument_list
(string
(string_start)
(string_content)
(string_end))))))))))))
================================================================================
Builtin classes
================================================================================
for action in actions:
match action:
case {"text": str(message), "color": str(c)}:
ui.set_text_color(c)
ui.display(message)
case {"sleep": float(duration)}:
ui.wait(duration)
case {"sound": str(url), "format": "ogg"}:
ui.play(url)
case {"sound": _, "format": _}:
warning("Unsupported audio format")
--------------------------------------------------------------------------------
(module
(for_statement
(identifier)
(identifier)
(block
(match_statement
(identifier)
(block
(case_clause
(case_pattern
(dict_pattern
(string
(string_start)
(string_content)
(string_end))
(case_pattern
(class_pattern
(dotted_name
(identifier))
(case_pattern
(dotted_name
(identifier)))))
(string
(string_start)
(string_content)
(string_end))
(case_pattern
(class_pattern
(dotted_name
(identifier))
(case_pattern
(dotted_name
(identifier)))))))
(block
(expression_statement
(call
(attribute
(identifier)
(identifier))
(argument_list
(identifier))))
(expression_statement
(call
(attribute
(identifier)
(identifier))
(argument_list
(identifier))))))
(case_clause
(case_pattern
(dict_pattern
(string
(string_start)
(string_content)
(string_end))
(case_pattern
(class_pattern
(dotted_name
(identifier))
(case_pattern
(dotted_name
(identifier)))))))
(block
(expression_statement
(call
(attribute
(identifier)
(identifier))
(argument_list
(identifier))))))
(case_clause
(case_pattern
(dict_pattern
(string
(string_start)
(string_content)
(string_end))
(case_pattern
(class_pattern
(dotted_name
(identifier))
(case_pattern
(dotted_name
(identifier)))))
(string
(string_start)
(string_content)
(string_end))
(case_pattern
(string
(string_start)
(string_content)
(string_end)))))
(block
(expression_statement
(call
(attribute
(identifier)
(identifier))
(argument_list
(identifier))))))
(case_clause
(case_pattern
(dict_pattern
(string
(string_start)
(string_content)
(string_end))
(case_pattern)
(string
(string_start)
(string_content)
(string_end))
(case_pattern)))
(block
(expression_statement
(call
(identifier)
(argument_list
(string
(string_start)
(string_content)
(string_end))))))))))))
================================================================================
Complex case patterns on classes
================================================================================
match x:
case Something(): # no args
foo1()
case Something.Else(): # more complex class name
foo2()
case Point2D(0, 1, 2): # three args
foo3()
case Point3D(x=0, y=0, z=0): # kw args
foo4()
case Point3D(34, x=0, y=0, z=0): # positional + kw args
foo5()
case Point2D(0, 1, 2,): # three args + trail comma
foo6()
case Point3D(x=0, y=0, z=0,): # kw args + trail comma
foo7()
case Point3D(34, x=0, y=0, z=0,): # positional + kw args + trail comma
foo8()
--------------------------------------------------------------------------------
(module
(match_statement
(identifier)
(block
(case_clause
(case_pattern
(class_pattern
(dotted_name
(identifier))))
(comment)
(block
(expression_statement
(call
(identifier)
(argument_list)))))
(case_clause
(case_pattern
(class_pattern
(dotted_name
(identifier)
(identifier))))
(comment)
(block
(expression_statement
(call
(identifier)
(argument_list)))))
(case_clause
(case_pattern
(class_pattern
(dotted_name
(identifier))
(case_pattern
(integer))
(case_pattern
(integer))
(case_pattern
(integer))))
(comment)
(block
(expression_statement
(call
(identifier)
(argument_list)))))
(case_clause
(case_pattern
(class_pattern
(dotted_name
(identifier))
(case_pattern
(keyword_pattern
(identifier)
(integer)))
(case_pattern
(keyword_pattern
(identifier)
(integer)))
(case_pattern
(keyword_pattern
(identifier)
(integer)))))
(comment)
(block
(expression_statement
(call
(identifier)
(argument_list)))))
(case_clause
(case_pattern
(class_pattern
(dotted_name
(identifier))
(case_pattern
(integer))
(case_pattern
(keyword_pattern
(identifier)
(integer)))
(case_pattern
(keyword_pattern
(identifier)
(integer)))
(case_pattern
(keyword_pattern
(identifier)
(integer)))))
(comment)
(block
(expression_statement
(call
(identifier)
(argument_list)))))
(case_clause
(case_pattern
(class_pattern
(dotted_name
(identifier))
(case_pattern
(integer))
(case_pattern
(integer))
(case_pattern
(integer))))
(comment)
(block
(expression_statement
(call
(identifier)
(argument_list)))))
(case_clause
(case_pattern
(class_pattern
(dotted_name
(identifier))
(case_pattern
(keyword_pattern
(identifier)
(integer)))
(case_pattern
(keyword_pattern
(identifier)
(integer)))
(case_pattern
(keyword_pattern
(identifier)
(integer)))))
(comment)
(block
(expression_statement
(call
(identifier)
(argument_list)))))
(case_clause
(case_pattern
(class_pattern
(dotted_name
(identifier))
(case_pattern
(integer))
(case_pattern
(keyword_pattern
(identifier)
(integer)))
(case_pattern
(keyword_pattern
(identifier)
(integer)))
(case_pattern
(keyword_pattern
(identifier)
(integer)))))
(comment)
(block
(expression_statement
(call
(identifier)
(argument_list))))))))
================================================================================
Complex case patterns on complex numbers
================================================================================
match x:
case -3 + 5j:
pass
case -3 + 5j as b2:
pass
case 3j as b1, -3 + 5j as b2:
pass
case -3. + 5j:
pass
case 3 - 5.j:
pass
--------------------------------------------------------------------------------
(module
(match_statement
(identifier)
(block
(case_clause
(case_pattern
(complex_pattern
(integer)
(integer)))
(block
(pass_statement)))
(case_clause
(case_pattern
(as_pattern
(case_pattern
(complex_pattern
(integer)
(integer)))
(identifier)))
(block
(pass_statement)))
(case_clause
(case_pattern
(as_pattern
(case_pattern
(integer))
(identifier)))
(case_pattern
(as_pattern
(case_pattern
(complex_pattern
(integer)
(integer)))
(identifier)))
(block
(pass_statement)))
(case_clause
(case_pattern
(complex_pattern
(float)
(integer)))
(block
(pass_statement)))
(case_clause
(case_pattern
(complex_pattern
(integer)
(float)))
(block
(pass_statement))))))
================================================================================
Maybe sequence pattern right hand side precedence validation
================================================================================
match x:
case a1, *a2, a3:
pass
--------------------------------------------------------------------------------
(module
(match_statement
(identifier)
(block
(case_clause
(case_pattern
(dotted_name
(identifier)))
(case_pattern
(splat_pattern
(identifier)))
(case_pattern
(dotted_name
(identifier)))
(block
(pass_statement))))))