Providing a shorthand match case statement

Structural Pattern Matching As Standalone Boolean Expression

I don’t have a strong opinion on “syntax” at the moment, I mainly want to illustrate the benefits of this “construct” itself.

Syntax comments:

  • One thing to think about would be whether to support comma-separated patterns.
    Though it seems it’s not supported in match-case either (no example in pep-0636 tutorial).

  • Any of these will work for me:

    • match(<thing>, <pattern>)
    • match <thing>, <pattern>
    • <thing> match <pattern>
  • Following will likely not:

    • thing := pattern Conflicts with walrus operator
    • match <thing> as <pattern> Too many is, as etc would become hard to remember down the line

Usefulness of this construct:

With this proposal:

best of both worlds:

  • clear selection with structural pattern match, and
  • flexible logic with guard clauses using orphan if-else blocks
def cli(args: list[str]) -> None:

	if args match [("-h" | "--help"), *x]:
		print(attempt_help.format(command=Path(sys.argv[0]).stem), end="")
		return

	response: str = input(attempt_prompt).lower()
	print()

	if response != 'y':
		return

	match (args):
		case []:
			attempt(load.default_path())

		case [("-f" | "--file"), file]:
			attempt(file)

		case _:
			...

Current alternate 2: if-else & invert-select guard clause

benefit: clear logic flow. invert-select guard clause keep the main body separated.
problem: selection itself is messed up: IndexError when args is empty, requires needless LBYL or EAFP

def cli(args: list[str]) -> None:
	if args[0] in ["-h", "--help"]:
		print(attempt_help.format(command=Path(sys.argv[0]).stem), end="")
		return

	response: str = input(attempt_prompt).lower()
	print()

	if response != 'y':
		return

	match (args):
		case []:
			attempt(load.default_path())

		case [("-f" | "--file"), file]:
			attempt(file)

		case _:
			...

Current alternate 1: match-case structural matching statement

benefit: clear selection: very easy structural pattern matching
problem: logic is messed up: either violates DRY or becomes needlessly nested (here, a combo of both)

def cli(args: list[str]) -> None:
	response: str
	match (args):
		case []:
			response = input(attempt_prompt).lower()
			print()
			if response == 'y':
				attempt(load.default_path())

		case [("-f" | "--file"), file]:
			response = input(attempt_prompt).lower()
			if response == 'y':
				attempt(file)
			else:
				print()

		case [("-h" | "--help"), *x]:
			print(attempt_help.format(command=Path(sys.argv[0]).stem), end="")

		case _:
			...

P.S.

the “Your topic is similar to…” is much much much more useful than tedious search.
can that panel be brought up again once it’s dismissed?
as it covers over the preview, but i think preview and duplicate search are separate functionalities

Previous writeup before finding this one

I have skimmed various articles online, and it seems that:

  • structural pattern matching is available only via match-case which is a statement, and can’t be used as expression. (tutorial here: pep-0636)
  • re is limited to text pattern matching, not on structural matching of general python objects like match-case. (tutorial here: howto/regex)

am i right? or does there exist a way to use match-case like capability in an expression too?

this might seem similar to, but is not same as:

2 Likes