3.2. Match Literal

A literal pattern is useful to filter constant values in a structure. It looks like a Python literal (including some values like True, False and None). It only matches objects equal to the literal, and never binds.

3.2.1. With Strings

>>> user = 'Mark'
>>>
>>> match user:
...     case 'Mark':    print('Hello Mark')
...     case 'Melissa': print('Hello Melissa')
...     case 'Rick':    print('Hello Rick')
...     case 'Alex':    print('Hello Alex')
...     case 'Beth':    print('Hello Beth')
...     case 'Chris':   print('Hello Chris')
...
Hello Mark

3.2.2. With Numbers

>>> weekday = 3
>>>
>>> match weekday:
...     case 1: print('Monday')
...     case 2: print('Tuesday')
...     case 3: print('Wednesday')
...     case 4: print('Thursday')
...     case 5: print('Friday')
...     case 6: print('Saturday')
...     case 7: print('Sunday')
...
Wednesday

3.2.3. With Booleans

>>> status = True
>>>
>>> match status:
...     case True:  print('success')
...     case False: print('error')
...     case None:  print('in-progress')
...
success

3.2.4. Use Case - 0x01

>>> def weekday(number):
...     match number:
...         case 1: print('Monday')
...         case 2: print('Tuesday')
...         case 3: print('Wednesday')
...         case 4: print('Thursday')
...         case 5: print('Friday')
...         case 6: print('Saturday')
...         case 7: print('Sunday')
>>> weekday(1)
Monday
>>>
>>> weekday(2)
Tuesday
>>>
>>> weekday(7)
Sunday

3.2.5. Use Case - 0x02

>>> def html_color(name):
...     match name:
...         case 'red':   return '#ff0000'
...         case 'green': return '#00ff00'
...         case 'blue':  return '#0000ff'
>>>
>>>
>>> html_color('red')
'#ff0000'
>>>
>>> html_color('green')
'#00ff00'
>>>
>>> html_color('blue')
'#0000ff'

3.2.6. Use Case - 0x03

>>> def status(result):
...     match result:
...         case True:  return 'success'
...         case False: return 'error'
...         case None:  return 'in-progress'
>>>
>>>
>>> status(True)
'success'
>>>
>>> status(False)
'error'
>>>
>>> status(None)
'in-progress'

3.2.7. Use Case - 0x04

>>> def http_status(status_code):
...     match status_code:
...         case 400:   return 'Bad request'
...         case 401:   return 'Unauthorized'
...         case 402:   return 'Payment Required'
...         case 403:   return 'Forbidden'
...         case 404:   return 'Not found'
...         case 418:   return "I'm a teapot"
>>> http_status(400)
'Bad request'
>>>
>>> http_status(403)
'Forbidden'
>>>
>>> http_status(404)
'Not found'

3.2.8. Use Case - 0x05

>>> def say_hello(language):
...     match language:
...         case 'English': return 'Hello'
...         case 'German':  return 'Guten Tag'
...         case 'Spanish': return 'Hola'
...         case 'Polish':  return 'Witaj'
...         case _:         return "I don't speak this language"
>>> say_hello('English')
'Hello'
>>>
>>> say_hello('Polish')
'Witaj'
>>>
>>> say_hello('French')
"I don't speak this language"

3.2.9. Use Case - 0x06

>>> def count(*args):
...     match len(args):
...         case 3: return 'Three'
...         case 2: return 'Two'
...         case 1: return 'One'
...         case 0: return 'Zero'
>>>
>>>
>>> count(1, 2, 3)
'Three'
>>>
>>> count(1, 2)
'Two'
>>>
>>> count(1)
'One'
>>>
>>> count()
'Zero'

3.2.10. Use Case - 0x07

>>> def myrange(*args, **kwargs):
...     if kwargs:
...         raise TypeError('myrange() takes no keyword arguments')
...
...     match len(args):
...         case 3:
...             start = args[0]
...             stop = args[1]
...             step = args[2]
...         case 2:
...             start = args[0]
...             stop = args[1]
...             step = 1
...         case 1:
...             start = 0
...             stop = args[0]
...             step = 1
...         case 0:
...             raise TypeError('myrange expected at least 1 argument, got 0')
...         case _:
...             raise TypeError(f'myrange expected at most 3 arguments, got {len(args)}')
...
...     current = start
...     result = []
...     while current < stop:
...         result.append(current)
...         current += step
...     return result

3.2.11. Use Case - 0x08

>>> def myrange(*args, **kwargs):
...     match len(args):
...         case 3:
...             start, stop, step = args
...         case 2:
...             start, stop = args
...             step = 1
...         case 1:
...             start = 0
...             stop = args[0]
...             step = 1
...         case 0:
...             raise TypeError('myrange expected at least 1 argument, got 0')
...         case _:
...             raise TypeError(f'myrange expected at most 3 arguments, got {len(args)}')
...     ...

3.2.12. Use Case - 0x09

>>> def myrange(*args, **kwargs):
...     match len(args):
...         case 3: start, stop, step = args
...         case 2: [start, stop], step = args, 1
...         case 1: start, [stop], step = 0, args, 1
...         case 0: raise TypeError('myrange expected at least 1 argument, got 0')
...         case _: raise TypeError(f'myrange expected at most 3 arguments, got {len(args)}')
...     ...

3.2.13. Use Case - 0x10

>>> import argparse
>>>
>>> parser = argparse.ArgumentParser()
>>> _ = parser.add_argument('command', choices=['push', 'pull', 'commit'])
>>> args = parser.parse_args(['push'])
>>>
>>> match args.command:
...     case 'push': print('Pushing...')
...     case 'pull': print('Pulling...')
...     case _:      parser.error(f'{args.command!r} not yet implemented')
...
Pushing...